bolkedebruin / rdpgw Goto Github PK
View Code? Open in Web Editor NEWRemote Desktop Gateway in Go for deploying on Linux/BSD/Kubernetes
License: Apache License 2.0
Remote Desktop Gateway in Go for deploying on Linux/BSD/Kubernetes
License: Apache License 2.0
Is there any plan to emit events or execute some hooks/triggers and query the connection status
I am looking for a possibility to get a "connecting" event to be able to start the VM for the connecting user
and be able to query disconnected sessions to stop VM's after a period.
Hello, the project sounds promising and exciting. I would like to test it and install it on my Synology NAS. Unfortunately, I have difficulties with the installation. It would be easier if a ready-made image was available on hub.docker.com.
Is something already being thought of here?
Best regards
after running
cd dev/docker
docker-compose build
docker-compose up
I'm getting the following errors
rdpgw_1 | 2022/09/21 22:11:40 Cookies are used as session storage
rdpgw_1 | 2022/09/21 22:11:40 Starting remote desktop gateway server
rdpgw_1 | 2022/09/21 22:11:40 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.3:8080: connect: connection refused
rdpgw_1 | 2022/09/21 22:11:44 No valid `security.paatokenencryptionkey` specified (empty or not 32 characters). Setting to random
rdpgw_1 | 2022/09/21 22:11:44 Cookies are used as session storage
rdpgw_1 | 2022/09/21 22:11:44 Starting remote desktop gateway server
rdpgw_1 | 2022/09/21 22:11:44 Cannot get oidc provider: 404 Not Found: {"error":"RESTEASY003210: Could not find resource for full path: http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration"}
rdpgw_1 | 2022/09/21 22:11:51 No valid `security.paatokenencryptionkey` specified (empty or not 32 characters). Setting to random
rdpgw_1 | 2022/09/21 22:11:51 Cookies are used as session storage
rdpgw_1 | 2022/09/21 22:11:51 Starting remote desktop gateway server
I've tried to use example from dev/docker directory, but connection hangs up o initialization of remote connection.
In container log I see next message repeated some times:
2020/11/02 14:32:05 Client handshakeRequest from 10.65.11.25
2020/11/02 14:32:05 major: 1, minor: 0, version: 0, ext auth: 2
2020/11/02 14:32:05 Cannot read message from stream websocket: close 1000 (normal)
This message I also see when deploy in k8s cluster.
in config template given in a readme we have
# The default option 'auto' uses a certificate file if provided and found otherwise
# it uses letsencrypt to obtain a certificate, the latter requires that the host is reachable
# from letsencrypt servers. If TLS termination happens somewhere else (e.g. a load balancer)
# set this option to 'disable'. This is mutually exclusive with 'authentication: local'
# Note: rdp connections over a gateway require TLS
Tls: auto
but it's just wont work
as we can from code here, it requires DisableTls
key instead of just Tls
.
make
go mod tidy
go: finding github.com/spf13/cobra v1.1.3
go: finding github.com/spf13/viper v1.7.1
go: finding github.com/patrickmn/go-cache v2.1.0+incompatible
go: finding github.com/gorilla/websocket v1.4.2
go: finding github.com/coreos/go-oidc/v3 v3.0.0
go: finding github.com/gorilla/sessions v1.2.1
go: finding github.com/square/go-jose/v3 v3.0.0-20200630053402-0a67ce9b0693
go: finding github.com/prometheus/client_golang v1.10.0
go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/oauth2" (https fetch: Get https://golang.org/x/oauth2?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)
go: github.com/coreos/go-oidc/[email protected]: unknown revision v3.0.0
go: github.com/spf13/[email protected]: unknown revision v1.7.1
go: github.com/spf13/[email protected]: unknown revision v1.1.3
go: github.com/gorilla/[email protected]: unknown revision v1.4.2
go: github.com/prometheus/[email protected]: unknown revision v1.10.0
go: github.com/patrickmn/[email protected]+incompatible: unknown revision v2.1.0
go: github.com/gorilla/[email protected]: unknown revision v1.2.1
go: error loading module requirements
Makefile:51: recipe for target 'mod' failed
make: *** [mod] Error 1
Hi, I've this error after docker-compose up from /opt/rdpgw/dev/docker:
Cannot get oidc provider: Get "http://localhost:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 127.0.0.1:8080: connect: connection refused
How can I fix it?
Thank you
Currently only one fragment can be handled, it should be made more robust to check the length of the packet and wait for all data to arrive.
@bolkedebruin
can this be setup behind a nginx reverse proxy so that is can share the IP address with other websites, i know you can do this with mesh central, but the goals are slightly different
label:question
I was unable to get viper to allow setting of config items with environment variables. I was able to get it working by switching to koanf instead. There are a few other benefits to koanf, but the largest drawback is that it is case sensitive. The current implementation I have working allows for all lowercase, but the .yaml file is required to match the camel case defined in the configuration structs.
package config
import (
"github.com/knadh/koanf"
"github.com/knadh/koanf/parsers/yaml"
"github.com/knadh/koanf/providers/confmap"
"github.com/knadh/koanf/providers/env"
"github.com/knadh/koanf/providers/file"
"log"
"strings"
)
type Configuration struct {
Server ServerConfig `koanf:"server"`
OpenId OpenIDConfig `koanf:"openid"`
Caps RDGCapsConfig `koanf:"caps"`
Security SecurityConfig `koanf:"security"`
Client ClientConfig `koanf:"client"`
}
type ServerConfig struct {
GatewayAddress string `koanf:"gatewayaddress"`
Port int `koanf:"port"`
CertFile string `koanf:"certfile"`
KeyFile string `koanf:"keyfile"`
Hosts []string `koanf:"hosts"`
RoundRobin bool `koanf:"roundrobin"`
SessionKey string `koanf:"sessionkey"`
SessionEncryptionKey string `koanf:"sessionencryptionkey"`
SendBuf int `koanf:"sendbuf"`
ReceiveBuf int `koanf:"recievebuf"`
}
type OpenIDConfig struct {
ProviderUrl string `koanf:"providerurl"`
ClientId string `koanf:"clientid"`
ClientSecret string `koanf:"clientsecret"`
}
type RDGCapsConfig struct {
SmartCardAuth bool `koanf:"smartcardauth"`
TokenAuth bool `koanf:"tokenauth"`
IdleTimeout int `koanf:"idletimeout"`
RedirectAll bool `koanf:"redirectall"`
DisableRedirect bool `koanf:"disableredirect"`
EnableClipboard bool `koanf:"enableclipboard"`
EnablePrinter bool `koanf:"enableprinter"`
EnablePort bool `koanf:"enableport"`
EnablePnp bool `koanf:"enablepnp"`
EnableDrive bool `koanf:"enabledrive"`
}
type SecurityConfig struct {
PAATokenEncryptionKey string `koanf:"paatokenencryptionkey"`
PAATokenSigningKey string `koanf:"paatokensigningkey"`
UserTokenEncryptionKey string `koanf:"usertokenencryptionkey"`
UserTokenSigningKey string `koanf:"usertokensigningkey"`
VerifyClientIp bool `koanf:"verifyclientip"`
EnableUserToken bool `koanf:"enableusertoken"`
}
type ClientConfig struct {
NetworkAutoDetect int `koanf:"networkautodetect"`
BandwidthAutoDetect int `koanf:"bandwidthautodetect"`
ConnectionType int `koanf:"connectiontype"`
UsernameTemplate string `koanf:"usernametemplate"`
SplitUserDomain bool `koanf:"splituserdomain"`
DefaultDomain string `koanf:"defaultdomain"`
}
func ToCamel(s string) string {
s = strings.TrimSpace(s)
n := strings.Builder{}
n.Grow(len(s))
var capNext bool = true
for i, v := range []byte(s) {
vIsCap := v >= 'A' && v <= 'Z'
vIsLow := v >= 'a' && v <= 'z'
if capNext {
if vIsLow {
v += 'A'
v -= 'a'
}
} else if i == 0 {
if vIsCap {
v += 'a'
v -= 'A'
}
}
if vIsCap || vIsLow {
n.WriteByte(v)
capNext = false
} else if vIsNum := v >= '0' && v <= '9'; vIsNum {
n.WriteByte(v)
capNext = true
} else {
capNext = v == '_' || v == ' ' || v == '-' || v == '.'
if v == '.' {
n.WriteByte(v)
}
}
}
return n.String()
}
var Conf Configuration
func Load(configFile string) Configuration {
var k = koanf.New(".")
k.Load(confmap.Provider(map[string]interface{}{
"Server.CertFile": "server.pem",
"Server.KeyFile": "key.pem",
"Server.Port": 443,
"Client.NetworkAutoDetect": 1,
"Client.BandwidthAutoDetect": 1,
"Security.VerifyClientIp": true,
}, "."), nil)
if err := k.Load(file.Provider(configFile), yaml.Parser()); err != nil {
log.Fatalf("Error loading config from file: %v", err)
}
if err := k.Load(env.ProviderWithValue("RDPGW_", ".", func(s string, v string) (string, interface{}) {
key := strings.Replace(strings.ToLower(strings.TrimPrefix(s, "RDPGW_")), "__", ".", -1)
key = ToCamel(key)
return key, v
}), nil); err != nil {
log.Fatalf("Error loading config from file: %v", err)
}
koanfTag := koanf.UnmarshalConf{Tag: "koanf"}
k.UnmarshalWithConf("Server", &Conf.Server, koanfTag)
k.UnmarshalWithConf("OpenId", &Conf.OpenId, koanfTag)
k.UnmarshalWithConf("Caps", &Conf.Caps, koanfTag)
k.UnmarshalWithConf("Security", &Conf.Security, koanfTag)
k.UnmarshalWithConf("Client", &Conf.Client, koanfTag)
return Conf
}
With this, the environment variables must use double underscores for nested config items, and single underscores where there is camel case.
i.e.
Server:
CertFile: /certs/tls.crt
KeyFile: /certs/tls.key
OpenId:
ProviderUrl: https://auth.rdpgw.local
ClientId: rdpgw
==
RDPGW_SERVER__CERT_FILE="/certs/tls.crt"
RDPGW_SERVER_KEY_FILE="/certs/tls.key"
RDPGW_OPEN_ID__PROVIDER_URL="https://auth.rdpgw.local"
RDPGW_OPEN_ID__CLIENT_ID="rdpgw"
2022/09/01 16:12:31 Cookies are used as session storage
2022/09/01 16:12:31 Starting remote desktop gateway server
2022/09/01 16:12:31 TLS disabled - rdp gw connections require tls, make sure to have a terminator
2022/09/01 16:12:31 ListenAndServe: open : no such file or directory
getting this while trying to start docker container
happens only when tls is disabled (im using traefik as tls terminating proxy)
Looks like a typo HTTP_TUNNEL_REDIR_DISABLE_PORT
Drive mapping working now
const (
HTTP_TUNNEL_REDIR_ENABLE_ALL = 0x80000000
HTTP_TUNNEL_REDIR_DISABLE_ALL = 0x40000000
HTTP_TUNNEL_REDIR_DISABLE_DRIVE = 0x01
HTTP_TUNNEL_REDIR_DISABLE_PRINTER = 0x02
// HTTP_TUNNEL_REDIR_DISABLE_PORT = 0x03
HTTP_TUNNEL_REDIR_DISABLE_PORT = 0x04 // MS-TSGU 2.2.5.3.7 should be 0x4?
HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD = 0x08
HTTP_TUNNEL_REDIR_DISABLE_PNP = 0x10
)
Very interesting project - thought I'd give this a try.
3919a7e
)securecookie: the value is too long
2021/02/24 18:46:51 http: superfluous response.WriteHeader call from github.com/bolkedebruin/rdpgw/api.(*Config).HandleCallback (web.go:118)
Any idea? Is there a flag to get more debug output?
Thanks :)
When rdpgw is running in local auth mode, I was supposed to enter PAM credentials to authenticate myself but turns out mstsc in Windows doesn't support basic auth anymore. Even if I set gatewaycredentialssource
to 3 in my rdp file, it still sent credentials in NTLM.
Attached is a packet dump of handshake in cleartext.
rdp.zip
Am i supposed to create a host entry on the host file for keycloak -> 127.0.0.1 ?
For some reason keycloak:8080/auth doesn't work hence localhost:9443/connect fails because it redirects me to keycloak:8080 for authentication.
If i enter localhost:8080/auth. that works fine without issues.
If i enter keycloak:8080/auth, i get page not found error.
Hello,
i want to use RDPGW as RDP-Gateway for a office. I have created a AlmaLinux-VM and compiled it. When starting the binary, it throws a error
[myuser@RDPGWVM bin]$ ./rdpgw
2022/07/07 18:51:03 Cannot get oidc provider: Get "/.well-known/openid-configuration": unsupported protocol scheme ""
because i don't want to use openid, i would like to disable that whole functionality. How to do that?
By the way, the project, at least the config-file needs more documentation.
Thank you
Hi!
I just need to connect to xrdp desktop stored in kubernetes cluster without expose any container port.
I would like to use this as classic remote desktop gateway with password authentication to store .rdp files non changed on users PC. Is it possible?
The website/domain cert is managed at the load balancer level. There is no control over that and the certificate can't be shared. I'm unable to provide a valid certificate in the rdpgw.yaml file. Is there any way around that ?
Hello,
I wanted to know if ssl client certificate (token) is is available for authentication , I added the ca-cert of my pki, but i have this error message.
Thanks by advance
logs 2022/09/29 08:35:50 RemoteAddr: x.y.x.y:57259
2022/09/29 08:35:50 Client handshakeRequest from x.y.x.y
2022/09/29 08:35:50 major: 1, minor: 0, version: 0, ext auth: 1
2022/09/29 08:35:50 Cannot read message from stream websocket: close 1000 (normal)
2022/09/29 08:39:55 preferred_username not found in context
Running
git clone https://github.com/bolkedebruin/rdpgw.git
cd rdpgw/dev/docker
docker-compose build
docker-compose up
Gives this output.
Attaching to docker_xrdp_1, docker_keycloak_1, docker_rdpgw_1
xrdp_1 |
xrdp_1 | Current default time zone: 'Europe/Amsterdam'
xrdp_1 | Local time is now: Thu Mar 10 20:45:59 CET 2022.
xrdp_1 | Universal Time is now: Thu Mar 10 19:45:59 UTC 2022.
xrdp_1 |
xrdp_1 | Username: admin, Password: admin , Sudo: Y
rdpgw_1 | 2022/03/10 19:45:59 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
xrdp_1 | 2022-03-10 20:46:00,190 CRIT Supervisor is running as root. Privileges were not dropped because no user is specified in the config file. If you intend to run as root, you can set user=root in the config file to avoid this message.
xrdp_1 | 2022-03-10 20:46:00,190 INFO Included extra file "/etc/supervisor/conf.d/xrdp.conf" during parsing
xrdp_1 | 2022-03-10 20:46:00,199 INFO RPC interface 'supervisor' initialized
xrdp_1 | 2022-03-10 20:46:00,199 CRIT Server 'unix_http_server' running without any HTTP authentication checking
xrdp_1 | 2022-03-10 20:46:00,199 INFO supervisord started with pid 75
rdpgw_1 | 2022/03/10 19:46:00 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
keycloak_1 | Keycloak - Open Source Identity and Access Management
keycloak_1 |
keycloak_1 | Find more information at: https://www.keycloak.org/docs/latest
keycloak_1 |
keycloak_1 | Usage:
keycloak_1 |
keycloak_1 | kc.sh [OPTIONS] [COMMAND]
keycloak_1 |
keycloak_1 | Use this command-line tool to manage your Keycloak cluster.
keycloak_1 | Make sure the command is available on your "PATH" or prefix it with "./" (e.g.:
keycloak_1 | "./kc.sh") to execute from the current folder.
keycloak_1 |
keycloak_1 | Options:
keycloak_1 |
keycloak_1 | -cf, --config-file <file>
keycloak_1 | Set the path to a configuration file. By default, configuration properties are
keycloak_1 | read from the "keycloak.conf" file in the "conf" directory.
keycloak_1 | -h, --help This help message.
keycloak_1 | -v, --verbose Print out error details when running this command.
keycloak_1 | -V, --version Show version information
keycloak_1 |
keycloak_1 | Commands:
keycloak_1 |
keycloak_1 | build Creates a new and optimized server image.
keycloak_1 | start Start the server.
keycloak_1 | start-dev Start the server in development mode.
keycloak_1 | export Export data from realms to a file or directory.
keycloak_1 | import Import data from a directory or a file.
keycloak_1 | show-config Print out the current configuration.
keycloak_1 | tools Utilities for use and interaction with the server.
keycloak_1 | completion Generate bash/zsh completion script for kc.sh.
keycloak_1 |
keycloak_1 | Examples:
keycloak_1 |
keycloak_1 | Start the server in development mode for local development or testing:
keycloak_1 |
keycloak_1 | $ kc.sh start-dev
keycloak_1 |
keycloak_1 | Building an optimized server runtime:
keycloak_1 |
keycloak_1 | $ kc.sh build <OPTIONS>
keycloak_1 |
keycloak_1 | Start the server in production mode:
keycloak_1 |
keycloak_1 | $ kc.sh start <OPTIONS>
keycloak_1 |
keycloak_1 | Enable auto-completion to bash/zsh:
keycloak_1 |
keycloak_1 | $ source <(kc.sh tools completion)
keycloak_1 |
keycloak_1 | Please, take a look at the documentation for more details before deploying in
keycloak_1 | production.
keycloak_1 |
keycloak_1 | Use "kc.sh start --help" for the available options when starting the server.
keycloak_1 | Use "kc.sh <command> --help" for more information about other commands.
docker_rdpgw_1 exited with code 1
docker_keycloak_1 exited with code 0
xrdp_1 | 2022-03-10 20:46:01,201 INFO spawned: 'xrdp' with pid 77
xrdp_1 | 2022-03-10 20:46:01,202 INFO spawned: 'xrdp-sesman' with pid 78
docker_rdpgw_1 exited with code 1
rdpgw_1 | 2022/03/10 19:45:59 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:00 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:01 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
xrdp_1 | 2022-03-10 20:46:02,203 INFO success: xrdp entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
xrdp_1 | 2022-03-10 20:46:02,203 INFO success: xrdp-sesman entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
docker_rdpgw_1 exited with code 1
rdpgw_1 | 2022/03/10 19:45:59 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:00 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:01 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:02 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
docker_rdpgw_1 exited with code 1
rdpgw_1 | 2022/03/10 19:45:59 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:00 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:01 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:02 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:03 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
docker_rdpgw_1 exited with code 1
rdpgw_1 | 2022/03/10 19:45:59 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:00 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:01 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:02 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:03 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:05 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
docker_rdpgw_1 exited with code 1
rdpgw_1 | 2022/03/10 19:45:59 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:00 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:01 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:02 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:03 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:05 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:09 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
docker_rdpgw_1 exited with code 1
rdpgw_1 | 2022/03/10 19:45:59 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:00 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:01 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:02 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:03 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:05 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:09 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:15 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
docker_rdpgw_1 exited with code 1
rdpgw_1 | 2022/03/10 19:45:59 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:00 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp 172.18.0.2:8080: connect: connection refused
rdpgw_1 | 2022/03/10 19:46:01 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:02 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:03 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:05 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:09 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:15 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
rdpgw_1 | 2022/03/10 19:46:29 Cannot get oidc provider: Get "http://keycloak:8080/auth/realms/rdpgw/.well-known/openid-configuration": dial tcp: lookup keycloak on 127.0.0.11:53: server misbehaving
Hi,
I would like to report a security vulnerability in this project. Can you please create a security advisory and add me as a collaborator?
since we are using ssl/tls-offload via firewall it would be a nice to be able to turn off the tls encryption.
and as a bonus evaluating something like the x-proto and the x-forwarded-for headers and logging / displaying them would be a pretty large plus :)
ingo
Hi, I love this project and it can run like i expect. But i have a situation that, after user can rdp to server by using their rdp client. They have to input pwd manually to login. If i have a user credential, so can i inject it to rdp server from RDP gateway ?
This looks like a very promising project! Nice work.
Does it also support RDP over UDP for the remote desktop connection?
From the docs it reads like having 'any' in the list of hosts should allow you to modify the rdp file and connect to any host.
# Allow the user to connect to any host (insecure)
- any
Trying this and modifying the rdp file to connect to 10.111.111.101:3389 gives the following error.
There was a problem connecting to the remote resource. Ask your network administrator for help.
Looking at the logs, it's getting blocked because the host does not match the token host 'any'.
2022/03/15 02:09:05 Starting remote desktop gateway server
2022/03/15 02:10:29 Client handshakeRequest from 10.111.111.13
2022/03/15 02:10:29 major: 1, minor: 0, version: 0, ext auth: 2
2022/03/15 02:10:29 Tunnel create
2022/03/15 02:10:29 Tunnel auth
2022/03/15 02:10:29 Channel create
2022/03/15 02:10:29 Client specified host 10.111.111.101:3389 does not match token host any
2022/03/15 02:10:29 Not allowed to connect to 10.111.111.101:3389 by policy handler
If I add in 10.111.111.101:3389 to the list of hosts the .rdp file downloaded seems to be for a random host with 'roundRobin' set to false. When the host is changed to another host that is specified in the configuration file, I still receive the 'not allowed to connect' message.
2022/03/15 02:23:04 Client handshakeRequest from 10.111.111.13
2022/03/15 02:23:04 major: 1, minor: 0, version: 0, ext auth: 2
2022/03/15 02:23:04 Tunnel create
2022/03/15 02:23:04 Tunnel auth
2022/03/15 02:23:04 Channel create
2022/03/15 02:23:04 Client specified host 10.111.111.101:3389 does not match token host 10.111.111.103:3389
2022/03/15 02:23:04 Not allowed to connect to 10.111.111.101:3389 by policy handler
Example config file:
server:
certFile: /certs/tls.crt
keyFile: /certs/tls.key
gatewayAddress: rdpgw.demo.cybertrol.app
port: 9443
hosts:
- 10.111.111.101:3389
- 10.111.111.102:3389
- 10.111.111.103:3389
- 10.111.111.104:3389
- 10.111.111.105:3389
- 10.111.111.106:3389
- any
roundRobin: false
sessionKey: thisisasessionkeyreplacethisjetz
sessionEncryptionKey: thisisasessionkeyreplacethisnunu
caps:
smartCardAuth: false
tokenAuth: true
idleTimeout: 60
enablePrinter: false
enablePort: false
enablePnp: false
enableDrive: false
enableClipboard: true
openId:
providerUrl: https://auth.demo.domain.com
clientId: rdpgw
clientSecret: 01cd304c-6f43-4480-9479-618eb6fd578f
client:
usernameTemplate: "domain\\{{ username }}"
networkAutoDetect: 0
bandwidthAutoDetect: 1
ConnectionType: 6
SplitUserDomain: true
security:
PAATokenSigningKey: prettypleasereplacemeinproductio
UserTokenEncryptionKey: prettypleasereplacemeinproductio
EnableUserToken: true
VerifyClientIp: false
With that I have a few questions.
I try to intercept PKT_TYPE_ DATA.
Can I use this to record a user's session? Have any other friends tried?
Best
Gemone
Hello!
This project looks very promissing, i only have seen guacamole server which a very huge frankenstein and so complex...
Your RDP GW looks awesome, but i just can't figure out how to install it, is there any tutorial, installation documentation, or a blog post, etc? i'm unfamiliar with Keycloak how should i configure it to work with rdpgw?
can you point me to the right path plz?
I have a Debian KVM server with several windows VM's, currently i'm just port forwarding the RDP ports to each VM, but i'd love to use your software as a frontend to all of that.
Kudos for your project!
Hope to hear back from you...
Best regards.
I've been trying to get rdpgw to run for 2 days now. It does not reveal to me what exactly has to be set up where with rdp. I would be very grateful if there would be detailed instructions. Or a complete docker image
Hello,
i try to install rdpgw in ubuntu server and it fails.
here's the issue
thanks by advance
#make
go mod tidy -compat=1.19
flag provided but not defined: -compat
usage: go mod tidy [-v]
Run 'go help mod tidy' for details.
make: *** [Makefile:53: mod] Error 2
I'm looking for a solution to connect securely to internal RDP servers from remote using Apache Guacamole.
My idea is to run this rdpgw on a non standard port and configure the firewall so that it is only publicly reachable from the Guacamole server.
Apache Guacamole does support Remote Desktop Gateways which are configurable with Hostname/IP, Port, Username, Password and Domain.
As far as I know there is no special support for certificate based authentication or OpenID or anything other than Username / Password authentication.
Is it possible to configure this RDP Gateway implementation, so that it would work under the given circumstances?
Greetings.
Can you tell me how to enable logs in rdpgw.
Built and raised from the wizard in the docker, trying to check authentication connection via keycloak, but it gives a security error. Maybe the logs will tell me more details.
update:
I set up this connection, client -> https:443(public cert domain.com) -> reverse proxy -> https:9443 -> rdpgw -> .
rdpgw -> keycloak in docker http://keycloak:8080/realms/test
rdpgw -> rds server :3389 + internal cert (domain.local)
The outdated ms vclient v8 for mac, with remotefx support, crashes when starting in fullscreen.
Hello,
First, I would like to thank you for this great project. It's always good to have FOSS alternatives to Windows-only, closed-source softwares.
I have a question about these lines of code (in configuration.go
):
if Conf.Server.Authentication == "local" && Conf.Server.DisableTLS {
log.Fatalf("basicauth=local and disabletls are mutually exclusive")
}
Is there a technical limitation that prevent using rdpgw behind a reverse proxy with a local authentication, or you did this to enforce end-to-end credentials encryption ?
Thank you
A deprecated keycloak image is used in the docker compose. For security reasons, this should be updated. See also: https://quay.io/repository/keycloak/keycloak?tag=latest&tab=tags
just wondering - what is the current status of the RDP protocol licensing from Microsoft... has it been released for general implementation? I see it used both for linux and windows servers, but just wondering if this is generally OK or have folks gotten licenses to use it?
Hi!
Sorry, I don't speak much English.
Im compile your project. Configuration succes and run rdpgw binary. Try connect websocet application writte error massage:
runtime error: invalid memory address or nil pointer dereference goroutine 51 [running]: net/http.(*conn).serve.func1() net/http/server.go:1850 +0xbf panic({0xa76f00, 0x102c100}) runtime/panic.go:890 +0x262 github.com/bolkedebruin/rdpgw/cmd/rdpgw/api.(*Config).HandleDownload(0xc00022b540, {0xc39e80, 0xc000458000}, 0xc00015a700) github.com/bolkedebruin/rdpgw/cmd/rdpgw/api/web.go:279 +0xae2 net/http.HandlerFunc.ServeHTTP(...) net/http/server.go:2109 github.com/bolkedebruin/rdpgw/cmd/rdpgw/api.(*Config).BasicAuth.func1({0xc39e80, 0xc000458000}, 0xc00009ce00) github.com/bolkedebruin/rdpgw/cmd/rdpgw/api/basic.go:52 +0x59b net/http.HandlerFunc.ServeHTTP(0xc3a858?, {0xc39e80?, 0xc000458000?}, 0xc32e00?) net/http/server.go:2109 +0x2f github.com/bolkedebruin/rdpgw/cmd/rdpgw/common.EnrichContext.func1({0xc39e80, 0xc000458000}, 0xc00009cc00) github.com/bolkedebruin/rdpgw/cmd/rdpgw/common/remote.go:41 +0x282 net/http.HandlerFunc.ServeHTTP(0xc00001baf0?, {0xc39e80?, 0xc000458000?}, 0x0?) net/http/server.go:2109 +0x2f net/http.(*ServeMux).ServeHTTP(0xc00013687d?, {0xc39e80, 0xc000458000}, 0xc00009cc00) net/http/server.go:2487 +0x149 net/http.serverHandler.ServeHTTP({0xc0000a0570?}, {0xc39e80, 0xc000458000}, 0xc00009cc00) net/http/server.go:2947 +0x30c net/http.(*conn).serve(0xc000000280, {0xc3a858, 0xc0002477a0}) net/http/server.go:1991 +0x607 created by net/http.(*Server).Serve net/http/server.go:3102 +0x4db
Problem maked patch: https://github.com/bolkedebruin/rdpgw/commit/f94e73b1ecd674771f1e1f4ea4417ae138f76934
Im try modify old source code manual adding modification. Compoile work not problem.
Try runing new binary replaced error massage.
Thanks your wok and help!
first off, can I disable openid? I just want a simple rdpgw I can install standalone on jump box
docs: key(s) in rdpgw.yaml should be only 32 characters - I got an error about crypto/aes key being 33
I downloaded rdpgw-1.0-stable and built rdpgw on ubuntu 20.04
I think I have openid working with Google - looks like Google part works and it redirects me. There's an auth.json with tokens in it. But on https://localhost:9443/connect I get
cannot find session or user
the logs show:
2020/12/10 13:53:51 Starting remote desktop gateway server
2020/12/10 13:53:56 preferred_username not found in context
2020/12/10 13:58:54 Client handshakeRequest from 172.24.128.1
2020/12/10 13:58:54 major: 1, minor: 0, version: 0, ext auth: 0
2020/12/10 13:58:54 Tunnel create
2020/12/10 13:58:54 http: panic serving 172.24.128.1:49991: runtime error: invalid memory address or nil pointer dereference
goroutine 11 [running]:
net/http.(*conn).serve.func1(0xc000438960)
/usr/lib/go-1.13/src/net/http/server.go:1767 +0x139
panic(0xb0e100, 0x1173360)
/usr/lib/go-1.13/src/runtime/panic.go:679 +0x1b2
github.com/bolkedebruin/rdpgw/security.VerifyPAAToken(0xcdec20, 0xc0001426f0, 0x0, 0x0, 0x3f, 0x0, 0x0)
/home/jmorrison/rdpgw-1.0-stable/security/jwt.go:39 +0x5d
github.com/bolkedebruin/rdpgw/protocol.(*Server).Process(0xc0001b8660, 0xcdec20, 0xc0001426f0, 0x0, 0x0)
/home/jmorrison/rdpgw-1.0-stable/protocol/server.go:89 +0xf00
github.com/bolkedebruin/rdpgw/protocol.(*Gateway).handleWebsocketProtocol(0xc00016e058, 0xcdec20, 0xc0001426f0, 0xc0002aa000, 0xc0001ba050)
/home/jmorrison/rdpgw-1.0-stable/protocol/gateway.go:98 +0x10f
github.com/bolkedebruin/rdpgw/protocol.(*Gateway).HandleGatewayProtocol(0xc00016e058, 0xcdc6e0, 0xc000472700, 0xc0001ca500)
/home/jmorrison/rdpgw-1.0-stable/protocol/gateway.go:84 +0x7b8
net/http.HandlerFunc.ServeHTTP(0xc0003a8640, 0xcdc6e0, 0xc000472700, 0xc0001ca500)
/usr/lib/go-1.13/src/net/http/server.go:2007 +0x44
github.com/bolkedebruin/rdpgw/common.EnrichContext.func1(0xcdc6e0, 0xc000472700, 0xc0001ca200)
/home/jmorrison/rdpgw-1.0-stable/common/remote.go:41 +0x41a
net/http.HandlerFunc.ServeHTTP(0xc000416940, 0xcdc6e0, 0xc000472700, 0xc0001ca200)
/usr/lib/go-1.13/src/net/http/server.go:2007 +0x44
net/http.(*ServeMux).ServeHTTP(0x1189140, 0xcdc6e0, 0xc000472700, 0xc0001ca200)
/usr/lib/go-1.13/src/net/http/server.go:2387 +0x1bd
net/http.serverHandler.ServeHTTP(0xc000458000, 0xcdc6e0, 0xc000472700, 0xc0001ca200)
/usr/lib/go-1.13/src/net/http/server.go:2802 +0xa4
net/http.(*conn).serve(0xc000438960, 0xcdeb60, 0xc0001a0240)
/usr/lib/go-1.13/src/net/http/server.go:1890 +0x875
created by net/http.(*Server).Serve
/usr/lib/go-1.13/src/net/http/server.go:2928 +0x384
Hey,
currently I don't see a good way to Authorize Users to Hosts (with the GW, not the Host). My suggestion would be, that an OpenId Provider like Keycloak can add a Host
Claim to the Access Token, which consists of an array of hosts. The user is than only allowed these hosts.
Access Token Snippet:
...
"hosts" : [
"0.0.0.0:3389",
"1.1.1.1:3389"
],
...
In Keycloak you could create a role for every host and assign the roles to users. Then you can use a Custom Client Scope to create the host claim.
Hi,
do you have an example of a client implementation?
I'm currently building an application to tunnel non-rdp traffic through an rd gateway server and can't get the tunnel initialization to work
My first tries are implemented here: https://github.com/develerik/rdtunnel
It always gets stuck at receiving the handshake response
this is error:
go: github.com/coreos/go-oidc/[email protected]: Get "https://goproxy.cn/github.com/coreos/go-oidc/v3/@v/v3.0.0-alpha.1.mod": dial tcp: lookup goproxy.cn on 223.5.5.5:53: read udp 10.0.8.156:33324->223.5.5.5:53: i/o timeout
is it because my device not connect to intrernet?
If that's the case,pelease tell me how build when i was offline. thinks!
hello, i use windows mstsc client to connect to this rdpgw by gateway method, i want to get some gw account info from rdpgw, not rdp server account, but i have't analyse it. can give me some ideas?
Hi there,
Very useful project. I appreciate the effort her.
I was trying to use this implementation on linux and tried rdp with remmina. But it seems to fail due to NTLM negotiation failures. I see people getting it to work, not sure what am I missing. Plz help.
21:26:54:263] [51107:52041] [DEBUG][com.winpr.sspi] - InitSecurityInterfaceExA
[21:26:54:263] [51107:52041] [DEBUG][com.winpr.sspi.NTLM] - change
state from NTLM_STATE_INITIAL to NTLM_STATE_INITIAL
[21:26:54:263] [51107:52041] [DEBUG][com.winpr.sspi.NTLM] - change
state from NTLM_STATE_INITIAL to NTLM_STATE_NEGOTIATE
[21:26:54:263] [51107:52041] [DEBUG][com.winpr.sspi.NTLM] - Write
flags [0xe20882b7]
NTLMSSP_NEGOTIATE_UNICODE|NTLMSSP_NEGOTIATE_OEM|NTLMSSP_REQUEST_TARGET|NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL|NTLMSSP_NEGOTIATE_LM_KEY|NTLMSSP_NEGOTIATE_NTLM|NTLMSSP_NEGOTIATE_ALWAYS_SIGN|NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY|NTLMSSP_NEGOTIATE_VERSION|NTLMSSP_NEGOTIATE_128|NTLMSSP_NEGOTIATE_KEY_EXCH
[21:26:54:263] [51107:52041] [DEBUG][com.winpr.sspi.NTLM] - change
state from NTLM_STATE_NEGOTIATE to NTLM_STATE_CHALLENGE
[21:26:54:263] [51107:52041] [DEBUG][com.freerdp.core.gateway.rdg] -
Unexpected NTLM challenge HTTP status: 101
[21:26:54:264] [51107:52041] [ERROR][com.freerdp.core.nego] - Protocol
Security Negotiation Failure
[21:26:54:264] [51107:52041] [ERROR][com.freerdp.core] -
rdp_client_connect:freerdp_set_last_error_ex
ERRCONNECT_SECURITY_NEGO_CONNECT_FAILED [0x0002000C]
[21:26:54:264] [51107:52041] [ERROR][com.freerdp.core.connection] -
Error: protocol security negotiation or connection failure
** (org.remmina.Remmina:51107): DEBUG: 21:26:54.417: [postcommand] (null)
** (org.remmina.Remmina:51107): DEBUG: 21:26:54.417: [postcommand] updated to:
It does look like the connection cannot be upgraded to websocket, but more investigation i�s required. It works still with 10.7.1
Plausible reason is the following entry from the release notes:
Improved compatibility with third-party network devices and load balancers for workspace download and RD Gateway-based connections.
Hie,
Thanks a lot for your project I'll try to find a substitute to MS RDP Gateway to connect to single desktops.
I try to install RDPGW to a raspberry pi 3 with raspbian.
In this raspberry I have a functional installation of apache with a c# webservice in mono from a project of mine.
I have installed GO 1.16 but when I try to make your project it return to me this errors:
"cmd/rdpgw/protocol/server.go:321:3: constant 2147483648 overflows int
make: *** [Makefile:37: /home/pi/rdpgw-master/bin/rdpgw] Error 2"
Where I was wrong?
Thanks a lot,
Francesco
docker-compose build fails with:
build github.com/bolkedebruin/rdpgw: cannot find module for path crypto/ed25519
due to Debian buster using golang version 1.11.
Using golang 1.14.
trying to connect from windows MSTSC to a windows server getting the below errors
2021/07/02 11:35:16 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:16 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:16 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:16 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:16 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:16 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 Client handshakeRequest from 192.168.4.106
2021/07/02 11:35:17 major: 1, minor: 0, version: 0, ext auth: 2
2021/07/02 11:35:17 Cannot read message from stream websocket: close 1000 (normal)
2021/07/02 11:35:17 http: TLS handshake error from 192.168.4.106:59149: EOF
When connecting to the rdp-gw running on MacOS and using Microsoft Remote Desktop on MacOS, I get "2 caps are required by the server, but the client does not support them". Does anyone have this setup running of does anyone has any idea what could be wrong here?
when Setup 5/13,Timeout exception found,The specific information is: fatal:go: github.com/coreos/go-oidc/[email protected]:Get "https:proxy.golang.org/github.com/coreos/go-oidc/v3/@v/v3.0.0.mod": dial tcp 142.251.42.241:44 : i/o timeout
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.