I know that Yggdrasil uses E2E data encryption, but as an additional layer in tls:// and wss:// schemes, FakeTLS 1.3 encryption is used to hide metadata.
FakeTLS means that a temporary certificate is generated each time Yggdrasil is launched. The validity of this certificate is not verified by Ygg clients. This allows for a MiTM attack.
src/core/tls.go
func (c *Core) generateTLSConfig(cert *tls.Certificate) (*tls.Config, error) {
config := &tls.Config{
Certificates: []tls.Certificate{*cert},
ClientAuth: tls.NoClientCert,
GetClientCertificate: func(cri *tls.CertificateRequestInfo) (*tls.Certificate, error) {
return cert, nil
},
VerifyPeerCertificate: c.verifyTLSCertificate,
VerifyConnection: c.verifyTLSConnection,
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS13,
}
return config, nil
}
func (c *Core) verifyTLSCertificate(_ [][]byte, _ [][]*x509.Certificate) error {
return nil
}
func (c *Core) verifyTLSConnection(_ tls.ConnectionState) error {
return nil
}
src/core/link_tls.go
type linkTLS struct {
phony.Inbox
*links
tcp *linkTCP
listener *net.ListenConfig
config *tls.Config
}
func (l *links) newLinkTLS(tcp *linkTCP) *linkTLS {
lt := &linkTLS{
links: l,
tcp: tcp,
listener: &net.ListenConfig{
Control: tcp.tcpContext,
KeepAlive: -1,
},
config: l.core.config.tls.Clone(),
}
return lt
}
A simple example of MiTM using SSLproxy tool:
10.4.4.6 (Client) , 10.4.4.10/10.5.5.10 - gateway (Attacker) and 10.5.5.5 (Server)
Starting main event loop.
SNI peek: [n/a] [complete], fd=31
Connecting to [10.5.5.5]:443
===> Original server certificate:
Subject DN: /C=YG/CN=0c1776253aaeb16cf4c4651e031addfe3f2b5db26f82fb43ebd5990b2dd357ae
Common Names: 0c1776253aaeb16cf4c4651e031addfe3f2b5db26f82fb43ebd5990b2dd357ae
Fingerprint: D7:FF:54:E6:1A:6C:CD:F3:29:87E1:8B:D4:17:DA:D7:0A:C9:6C:01
Certificate cache: MISS
===> Forged server certificate:
Subject DN: /C=YG/CN=0c1776253aaeb16cf4c4651e031addfe3f2b5db26f82fb43ebd5990b2dd357ae
Common Names: 0c1776253aaeb16cf4c4651e031addfe3f2b5db26f82fb43ebd5990b2dd357ae
Fingerprint: 9C:E5:0A:52:FC:6E:82:B2:05:7E42:D0:F2:F6:EF:67:E5:91:CA:39
CONN: ssl 10.4.4.6 37756 10.5.5.5 443 sni:- names:0c1776253aaeb16cf4c4651e031addfe3f2b5db26f82fb43ebd5990b2dd357ae sproto:TLSv1.3:TLS_AES_128_GCM_SHA256 dproto:TLSv1.3:TLS_AES_128_GCM_SHA256 origcrt:D7FF54E61A6CCDF32987E18BD417DAD70AC96C01 usedcrt:9CE50A52FC6E82B2057E42D0F2F6EF67E591CA39 user:-
SSL connected to [10.5.5.5]:443 TLSv1.3 TLS_AES_128_GCM_SHA256
CLIENT_RANDOM 59B962A56443027ED25643AF713B1B0A20C6F1555F75B8ECD6DA0B9D83533384 70995292118DA3214E7E11ECCBB4E53F9742DBD32762869458E838F71999DE9800000000000000000000000000000000
SSL_free() in state 00000001 = 0001 = SSLOK (SSL negotiation finished successfully) [connect socket]
SSL_free() in state 00000001 = 0001 = SSLOK (SSL negotiation finished successfully) [accept socket]
Inside TLS

Handshake
My suggestions:
- Add a path to certificate in yggdrasil.conf
- Add the key
-tlshash when adding a peer (tls/wss), and make it mandatory.
- Compare
-tlshash and server certificate hash, if not match - reject the connection.
- Hash output in server logs.
I know that Yggdrasil uses E2E data encryption, but as an additional layer in tls:// and wss:// schemes, FakeTLS 1.3 encryption is used to hide metadata.
FakeTLS means that a temporary certificate is generated each time Yggdrasil is launched. The validity of this certificate is not verified by Ygg clients. This allows for a MiTM attack.
src/core/tls.go
src/core/link_tls.go
A simple example of MiTM using SSLproxy tool:
10.4.4.6 (Client) , 10.4.4.10/10.5.5.10 - gateway (Attacker) and 10.5.5.5 (Server)
Inside TLS
Handshake
My suggestions:
-tlshashwhen adding a peer (tls/wss), and make it mandatory.-tlshashand server certificate hash, if not match - reject the connection.