mirror of
https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake.git
synced 2025-10-13 20:11:19 -04:00
Add raw DTLS fingerprints
This commit is contained in:
parent
fd9f08d986
commit
0976198523
6 changed files with 60 additions and 17 deletions
|
@ -37,6 +37,7 @@ import (
|
||||||
|
|
||||||
"github.com/pion/ice/v4"
|
"github.com/pion/ice/v4"
|
||||||
"github.com/pion/webrtc/v4"
|
"github.com/pion/webrtc/v4"
|
||||||
|
"github.com/theodorsm/covert-dtls/pkg/fingerprints"
|
||||||
"github.com/xtaci/kcp-go/v5"
|
"github.com/xtaci/kcp-go/v5"
|
||||||
"github.com/xtaci/smux"
|
"github.com/xtaci/smux"
|
||||||
|
|
||||||
|
@ -120,6 +121,7 @@ type ClientConfig struct {
|
||||||
// CommunicationProxy is the proxy address for network communication
|
// CommunicationProxy is the proxy address for network communication
|
||||||
CommunicationProxy *url.URL
|
CommunicationProxy *url.URL
|
||||||
CovertDTLSConfig string
|
CovertDTLSConfig string
|
||||||
|
CovertDTLSFingerprint string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSnowflakeClient creates a new Snowflake transport client that can spawn multiple
|
// NewSnowflakeClient creates a new Snowflake transport client that can spawn multiple
|
||||||
|
@ -165,9 +167,12 @@ func NewSnowflakeClient(config ClientConfig) (*Transport, error) {
|
||||||
|
|
||||||
eventsLogger := event.NewSnowflakeEventDispatcher()
|
eventsLogger := event.NewSnowflakeEventDispatcher()
|
||||||
var transport *Transport
|
var transport *Transport
|
||||||
// TODO: Add fingerprint config
|
|
||||||
if config.CovertDTLSConfig != "" {
|
if config.CovertDTLSConfig != "" {
|
||||||
covertDTLSConfig := covertdtls.ParseConfigString(config.CovertDTLSConfig)
|
covertDTLSConfig := covertdtls.ParseConfigString(config.CovertDTLSConfig)
|
||||||
|
if config.CovertDTLSFingerprint != "" {
|
||||||
|
covertDTLSConfig.Fingerprint = fingerprints.ClientHelloFingerprint(*&config.CovertDTLSFingerprint)
|
||||||
|
}
|
||||||
transport = &Transport{dialer: NewCovertWebRTCDialerWithEventsAndProxy(broker, iceServers, max, eventsLogger, config.CommunicationProxy, &covertDTLSConfig), eventDispatcher: eventsLogger}
|
transport = &Transport{dialer: NewCovertWebRTCDialerWithEventsAndProxy(broker, iceServers, max, eventsLogger, config.CommunicationProxy, &covertDTLSConfig), eventDispatcher: eventsLogger}
|
||||||
} else {
|
} else {
|
||||||
transport = &Transport{dialer: NewWebRTCDialerWithEventsAndProxy(broker, iceServers, max, eventsLogger, config.CommunicationProxy), eventDispatcher: eventsLogger}
|
transport = &Transport{dialer: NewWebRTCDialerWithEventsAndProxy(broker, iceServers, max, eventsLogger, config.CommunicationProxy), eventDispatcher: eventsLogger}
|
||||||
|
|
|
@ -287,7 +287,17 @@ func (c *WebRTCPeer) preparePeerConnection(
|
||||||
|
|
||||||
s.SetNet(vnet)
|
s.SetNet(vnet)
|
||||||
|
|
||||||
if covertDTLSConfig.Mimic {
|
if covertDTLSConfig.Fingerprint != "" {
|
||||||
|
mimic := &mimicry.MimickedClientHello{}
|
||||||
|
err = mimic.LoadFingerprint(covertDTLSConfig.Fingerprint)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("NewPeerConnection ERROR: %s", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
profiles := utils.DefaultSRTPProtectionProfiles()
|
||||||
|
s.SetSRTPProtectionProfiles(profiles...)
|
||||||
|
s.SetDTLSClientHelloMessageHook(mimic.Hook)
|
||||||
|
} else if covertDTLSConfig.Mimic {
|
||||||
mimic := &mimicry.MimickedClientHello{}
|
mimic := &mimicry.MimickedClientHello{}
|
||||||
if covertDTLSConfig.Randomize {
|
if covertDTLSConfig.Randomize {
|
||||||
err = mimic.LoadRandomFingerprint()
|
err = mimic.LoadRandomFingerprint()
|
||||||
|
|
|
@ -126,6 +126,9 @@ func socksAcceptLoop(ln *pt.SocksListener, config sf.ClientConfig, shutdown chan
|
||||||
if arg, ok := conn.Req.Args.Get("covertdtls-config"); ok {
|
if arg, ok := conn.Req.Args.Get("covertdtls-config"); ok {
|
||||||
config.CovertDTLSConfig = arg
|
config.CovertDTLSConfig = arg
|
||||||
}
|
}
|
||||||
|
if arg, ok := conn.Req.Args.Get("covertdtls-fingerprint"); ok {
|
||||||
|
config.CovertDTLSFingerprint = arg
|
||||||
|
}
|
||||||
transport, err := sf.NewSnowflakeClient(config)
|
transport, err := sf.NewSnowflakeClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Reject()
|
conn.Reject()
|
||||||
|
@ -177,7 +180,8 @@ func main() {
|
||||||
max := flag.Int("max", DefaultSnowflakeCapacity,
|
max := flag.Int("max", DefaultSnowflakeCapacity,
|
||||||
"capacity for number of multiplexed WebRTC peers")
|
"capacity for number of multiplexed WebRTC peers")
|
||||||
versionFlag := flag.Bool("version", false, "display version info to stderr and quit")
|
versionFlag := flag.Bool("version", false, "display version info to stderr and quit")
|
||||||
covertDTLSConfig := flag.String("covertdtls-config", "", "Configuration of dtls mimicking and randomization: mimic, randomize, randomizemimic")
|
covertDTLSConfig := flag.String("covertdtls-config", "", "Configuration of DTLS mimicking and randomization: mimic, randomize, randomizemimic")
|
||||||
|
covertDTLSfingerprint := flag.String("covertdtls-fingerprint", "", "Mimicking of a raw DTLS fingerprint")
|
||||||
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
oldLogToStateDir := flag.Bool("logToStateDir", false, "use -log-to-state-dir instead")
|
oldLogToStateDir := flag.Bool("logToStateDir", false, "use -log-to-state-dir instead")
|
||||||
|
@ -245,6 +249,7 @@ func main() {
|
||||||
KeepLocalAddresses: *keepLocalAddresses || *oldKeepLocalAddresses,
|
KeepLocalAddresses: *keepLocalAddresses || *oldKeepLocalAddresses,
|
||||||
Max: *max,
|
Max: *max,
|
||||||
CovertDTLSConfig: *covertDTLSConfig,
|
CovertDTLSConfig: *covertDTLSConfig,
|
||||||
|
CovertDTLSFingerprint: *covertDTLSfingerprint,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin goptlib client process.
|
// Begin goptlib client process.
|
||||||
|
|
|
@ -48,6 +48,8 @@ Usage of ./proxy:
|
||||||
maximum concurrent clients (default is to accept an unlimited number of clients)
|
maximum concurrent clients (default is to accept an unlimited number of clients)
|
||||||
-covertdtls-config string
|
-covertdtls-config string
|
||||||
Configuration of dtls mimicking and randomization: mimic, randomize, randomizemimic
|
Configuration of dtls mimicking and randomization: mimic, randomize, randomizemimic
|
||||||
|
-covertdtls-fingerprint string
|
||||||
|
Mimicking of a raw DTLS fingerprint
|
||||||
-disable-stats-logger
|
-disable-stats-logger
|
||||||
disable the exposing mechanism for stats using logs
|
disable the exposing mechanism for stats using logs
|
||||||
-dtls-randomize
|
-dtls-randomize
|
||||||
|
|
|
@ -430,7 +430,17 @@ func (sf *SnowflakeProxy) makeWebRTCAPI() *webrtc.API {
|
||||||
|
|
||||||
settingsEngine.SetDTLSInsecureSkipHelloVerify(true)
|
settingsEngine.SetDTLSInsecureSkipHelloVerify(true)
|
||||||
|
|
||||||
if sf.CovertDTLSConfig.Mimic {
|
if sf.CovertDTLSConfig.Fingerprint != "" {
|
||||||
|
mimic := &mimicry.MimickedClientHello{}
|
||||||
|
err := mimic.LoadFingerprint(sf.CovertDTLSConfig.Fingerprint)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("NewPeerConnection ERROR: %s", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
profiles := utils.DefaultSRTPProtectionProfiles()
|
||||||
|
settingsEngine.SetSRTPProtectionProfiles(profiles...)
|
||||||
|
settingsEngine.SetDTLSClientHelloMessageHook(mimic.Hook)
|
||||||
|
} else if sf.CovertDTLSConfig.Mimic {
|
||||||
mimic := &mimicry.MimickedClientHello{}
|
mimic := &mimicry.MimickedClientHello{}
|
||||||
if sf.CovertDTLSConfig.Randomize {
|
if sf.CovertDTLSConfig.Randomize {
|
||||||
err := mimic.LoadRandomFingerprint()
|
err := mimic.LoadRandomFingerprint()
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/theodorsm/covert-dtls/pkg/fingerprints"
|
||||||
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/ptutil/safelog"
|
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/ptutil/safelog"
|
||||||
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/covertdtls"
|
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/covertdtls"
|
||||||
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/event"
|
"gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/snowflake/v2/common/event"
|
||||||
|
@ -47,7 +48,8 @@ func main() {
|
||||||
verboseLogging := flag.Bool("verbose", false, "increase log verbosity")
|
verboseLogging := flag.Bool("verbose", false, "increase log verbosity")
|
||||||
ephemeralPortsRangeFlag := flag.String("ephemeral-ports-range", "", "Set the `range` of ports used for client connections (format:\"<min>:<max>\").\nIf omitted, the ports will be chosen automatically.")
|
ephemeralPortsRangeFlag := flag.String("ephemeral-ports-range", "", "Set the `range` of ports used for client connections (format:\"<min>:<max>\").\nIf omitted, the ports will be chosen automatically.")
|
||||||
versionFlag := flag.Bool("version", false, "display version info to stderr and quit")
|
versionFlag := flag.Bool("version", false, "display version info to stderr and quit")
|
||||||
covertDTLSConfig := flag.String("covertdtls-config", "", "Configuration of dtls mimicking and randomization: mimic, randomize, randomizemimic")
|
covertDTLSConfig := flag.String("covertdtls-config", "", "Configuration of DTLS mimicking and randomization: mimic, randomize, randomizemimic")
|
||||||
|
covertDTLSfingerprint := flag.String("covertdtls-fingerprint", "", "Mimicking of a raw DTLS fingerprint")
|
||||||
|
|
||||||
var ephemeralPortsRange []uint16 = []uint16{0, 0}
|
var ephemeralPortsRange []uint16 = []uint16{0, 0}
|
||||||
|
|
||||||
|
@ -94,6 +96,15 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cDTLSconfig covertdtls.CovertDTLSConfig
|
||||||
|
|
||||||
|
if *covertDTLSConfig != "" {
|
||||||
|
cDTLSconfig = covertdtls.ParseConfigString(*covertDTLSConfig)
|
||||||
|
}
|
||||||
|
if *covertDTLSfingerprint != "" {
|
||||||
|
cDTLSconfig.Fingerprint = fingerprints.ClientHelloFingerprint(*covertDTLSfingerprint)
|
||||||
|
}
|
||||||
|
|
||||||
proxy := sf.SnowflakeProxy{
|
proxy := sf.SnowflakeProxy{
|
||||||
PollInterval: *pollInterval,
|
PollInterval: *pollInterval,
|
||||||
Capacity: uint(*capacity),
|
Capacity: uint(*capacity),
|
||||||
|
@ -114,7 +125,7 @@ func main() {
|
||||||
AllowNonTLSRelay: *allowNonTLSRelay,
|
AllowNonTLSRelay: *allowNonTLSRelay,
|
||||||
|
|
||||||
SummaryInterval: *summaryInterval,
|
SummaryInterval: *summaryInterval,
|
||||||
CovertDTLSConfig: covertdtls.ParseConfigString(*covertDTLSConfig),
|
CovertDTLSConfig: cDTLSconfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
var logOutput = io.Discard
|
var logOutput = io.Discard
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue