From e8f3fc02599321cdfe73e65622db501bd33b04f3 Mon Sep 17 00:00:00 2001 From: Romain GERARD Date: Mon, 7 Dec 2020 10:29:35 +0100 Subject: [PATCH] \#65 Add host Header and TLS SNI override Former-commit-id: 5ddf5c5b7a8d1bd483ac063e5c09f058c80b820e Former-commit-id: d97bd60ef93720e94274be0d1cd50f1d742949dd [formerly df42280ad7675379c9b283f658e5e75c8c28f1a4] [formerly 95700181615ef2eaf461fdb3e0c67af4b8aa54e8 [formerly da23f33f04294a146a691f6d635884942ca00967 [formerly da23f33f04294a146a691f6d635884942ca00967 [formerly da23f33f04294a146a691f6d635884942ca00967 [formerly f40c007627bc5a26208c64cd3e5479a43a7a1c20]]]]] Former-commit-id: 3b061c8e6950a03ceb4f2e44651609f4d8899248 [formerly ee6563bdd95ec09d33aa6610d201a8f581137626] Former-commit-id: 3070702567889c7a53477714d65e4476e6056646 Former-commit-id: 1485f4efa64ed475d15780d316306feffb7b53e0 Former-commit-id: df44169b35e25e59ec9a3a818b38d0986ac68e02 Former-commit-id: 49e8fdce68b6b06f23c8b681163ac7e48b6e7075 [formerly 7277e9db3e5301faac5ef4dc7641f61d367353b0] Former-commit-id: b99e5bdd73ac1ee14db7a6509ea9ae4489873532 --- app/Main.hs | 14 ++++++++++++++ src/Tunnel.hs | 5 +++-- src/Types.hs | 2 ++ test/Spec.hs | 9 +++++++++ 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/Main.hs b/app/Main.hs index b1e8f76..fbf6c87 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -31,6 +31,8 @@ data WsTunnel = WsTunnel , verbose :: Bool , quiet :: Bool , pathPrefix :: String + , hostHeader :: String + , tlsSNI :: String , wsTunnelCredentials :: String } deriving (Show, Data, Typeable) @@ -69,6 +71,10 @@ cmdLine = WsTunnel &= typ "USER[:PASS]" , proxy = def &= explicit &= name "p" &= name "httpProxy" &= help "If set, will use this proxy to connect to the server" &= typ "USER:PASS@HOST:PORT" + , hostHeader = def &= explicit &= name "hostHeader" &= groupname "Client options" + &= help "If set, add the custom string as host http header" &= typ "String" &= groupname "Client options" + , tlsSNI = def &= explicit &= name "tlsSNI" &= groupname "Client options" + &= help "If set, use custom string in the SNI during TLS handshake" &= typ "String" &= groupname "Client options" , soMark = def &= explicit &= name "soMark" &= help "(linux only) Mark network packet with SO_MARK sockoption with the specified value. You need to use {root, sudo, capabilities} to run wstunnel when using this option" &= typ "int" , wsTunnelServer = def &= argPos 0 &= typ "ws[s]://wstunnelServer[:port]" @@ -228,6 +234,8 @@ runApp cfg serverInfo , upgradePrefix = pathPrefix cfg , upgradeCredentials = BC.pack $ wsTunnelCredentials cfg , udpTimeout = Main.udpTimeout cfg + , tlsSNI = BC.pack $ Main.tlsSNI cfg + , hostHeader = BC.pack $ Main.hostHeader cfg } toTcpLocalToRemoteTunnelSetting cfg serverInfo (TunnelInfo lHost lPort rHost rPort) = @@ -245,6 +253,8 @@ runApp cfg serverInfo , upgradePrefix = pathPrefix cfg , upgradeCredentials = BC.pack $ wsTunnelCredentials cfg , udpTimeout = Main.udpTimeout cfg + , tlsSNI = BC.pack $ Main.tlsSNI cfg + , hostHeader = BC.pack $ Main.hostHeader cfg } toUdpLocalToRemoteTunnelSetting cfg serverInfo (TunnelInfo lHost lPort rHost rPort) = @@ -262,6 +272,8 @@ runApp cfg serverInfo , upgradePrefix = pathPrefix cfg , upgradeCredentials = BC.pack $ wsTunnelCredentials cfg , udpTimeout = Main.udpTimeout cfg + , tlsSNI = BC.pack $ Main.tlsSNI cfg + , hostHeader = BC.pack $ Main.hostHeader cfg } toDynamicTunnelSetting cfg serverInfo (TunnelInfo lHost lPort _ _) = @@ -279,4 +291,6 @@ runApp cfg serverInfo , upgradePrefix = pathPrefix cfg , upgradeCredentials = BC.pack $ wsTunnelCredentials cfg , udpTimeout = Main.udpTimeout cfg + , tlsSNI = BC.pack $ Main.tlsSNI cfg + , hostHeader = BC.pack $ Main.hostHeader cfg } diff --git a/src/Tunnel.hs b/src/Tunnel.hs index 09603b8..40e09d7 100644 --- a/src/Tunnel.hs +++ b/src/Tunnel.hs @@ -65,7 +65,8 @@ tunnelingClientP cfg@TunnelSettings{..} app conn = onError $ do debug "Oppening Websocket stream" stream <- connectionToStream conn - let headers = if not (null upgradeCredentials) then [("Authorization", "Basic " <> B64.encode upgradeCredentials)] else [] + let headers = (if not (null upgradeCredentials) then [("Authorization", "Basic " <> B64.encode upgradeCredentials)] else []) + <> (if not (null hostHeader) then [("Host", hostHeader)] else []) ret <- WS.runClientWithStream stream serverHost (toPath cfg) WS.defaultConnectionOptions headers run debug "Closing Websocket stream" @@ -99,7 +100,7 @@ tlsClientP TunnelSettings{..} app conn = onError $ do , NC.settingDisableSession = False , NC.settingUseServerName = False } - connectionParams = NC.ConnectionParams { NC.connectionHostname = serverHost + connectionParams = NC.ConnectionParams { NC.connectionHostname = if tlsSNI == mempty then serverHost else BC.unpack tlsSNI , NC.connectionPort = serverPort , NC.connectionUseSecure = Just tlsSettings , NC.connectionUseSocks = Nothing diff --git a/src/Types.hs b/src/Types.hs index 3ebfd09..3730f09 100644 --- a/src/Types.hs +++ b/src/Types.hs @@ -79,6 +79,8 @@ data TunnelSettings = TunnelSettings , upgradePrefix :: String , upgradeCredentials :: ByteString + , tlsSNI :: ByteString + , hostHeader :: ByteString , udpTimeout :: Int } diff --git a/test/Spec.hs b/test/Spec.hs index dfe32fc..b428ee2 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -47,6 +47,9 @@ testTCPLocalToRemote useTLS = do , useSocks = False , upgradePrefix = "wstunnel" , udpTimeout = 0 + , upgradeCredentials = "" + , hostHeader = "toto.com" + , tlsSNI = "toto.com" } let client = runClient tunnelSetting @@ -104,6 +107,9 @@ testUDPLocalToRemote useTLS = do , useSocks = False , upgradePrefix = "wstunnel" , udpTimeout = -1 + , upgradeCredentials = "" + , hostHeader = "toto.com" + , tlsSNI = "toto.com" } let client = runClient tunnelSetting @@ -160,6 +166,9 @@ testSocks5Tunneling useTLS = do , useSocks = False , upgradePrefix = "wstunnel" , udpTimeout = -1 + , upgradeCredentials = "" + , hostHeader = "toto.com" + , tlsSNI = "toto.com" } let client = runClient tunnelSetting