config.go 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336
  1. /*
  2. * Copyright (c) 2016, Psiphon Inc.
  3. * All rights reserved.
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. *
  18. */
  19. package server
  20. import (
  21. "crypto/rand"
  22. "crypto/rsa"
  23. "crypto/x509"
  24. "encoding/base64"
  25. "encoding/hex"
  26. "encoding/json"
  27. "encoding/pem"
  28. "net"
  29. "os"
  30. "strconv"
  31. "strings"
  32. "sync/atomic"
  33. "time"
  34. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
  35. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/accesscontrol"
  36. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/crypto/ssh"
  37. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
  38. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/inproxy"
  39. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/osl"
  40. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/prng"
  41. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/protocol"
  42. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/tactics"
  43. "github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/values"
  44. "golang.org/x/crypto/nacl/box"
  45. )
  46. const (
  47. SERVER_CONFIG_FILENAME = "psiphond.config"
  48. SERVER_TRAFFIC_RULES_CONFIG_FILENAME = "psiphond-traffic-rules.config"
  49. SERVER_OSL_CONFIG_FILENAME = "psiphond-osl.config"
  50. SERVER_TACTICS_CONFIG_FILENAME = "psiphond-tactics.config"
  51. SERVER_ENTRY_FILENAME = "server-entry.dat"
  52. DEFAULT_SERVER_IP_ADDRESS = "127.0.0.1"
  53. WEB_SERVER_SECRET_BYTE_LENGTH = 32
  54. DISCOVERY_VALUE_KEY_BYTE_LENGTH = 32
  55. SSH_USERNAME_SUFFIX_BYTE_LENGTH = 8
  56. SSH_PASSWORD_BYTE_LENGTH = 32
  57. SSH_RSA_HOST_KEY_BITS = 2048
  58. SSH_OBFUSCATED_KEY_BYTE_LENGTH = 32
  59. SHADOWSOCKS_KEY_BYTE_LENGTH = 32
  60. PEAK_UPSTREAM_FAILURE_RATE_MINIMUM_SAMPLE_SIZE = 10
  61. PERIODIC_GARBAGE_COLLECTION = 120 * time.Second
  62. STOP_ESTABLISH_TUNNELS_ESTABLISHED_CLIENT_THRESHOLD = 20
  63. DEFAULT_LOG_FILE_REOPEN_RETRIES = 25
  64. )
  65. // Config specifies the configuration and behavior of a Psiphon
  66. // server.
  67. type Config struct {
  68. // LogLevel specifies the log level. Valid values are:
  69. // panic, fatal, error, warn, info, debug
  70. LogLevel string
  71. // LogFilename specifies the path of the file to log
  72. // to. When blank, logs are written to stderr.
  73. LogFilename string
  74. // LogFileReopenRetries specifies how many retries, each with a 1ms delay,
  75. // will be attempted after reopening a rotated log file fails. Retries
  76. // mitigate any race conditions between writes/reopens and file operations
  77. // performed by external log managers, such as logrotate.
  78. //
  79. // When omitted, DEFAULT_LOG_FILE_REOPEN_RETRIES is used.
  80. LogFileReopenRetries *int
  81. // LogFileCreateMode specifies that the Psiphon server should create a new
  82. // log file when one is not found, such as after rotation with logrotate
  83. // configured with nocreate. The value is the os.FileMode value to use when
  84. // creating the file.
  85. //
  86. // When omitted, the Psiphon server does not create log files.
  87. LogFileCreateMode *int
  88. // SkipPanickingLogWriter disables panicking when
  89. // unable to write any logs.
  90. SkipPanickingLogWriter bool
  91. // DiscoveryValueHMACKey is the network-wide secret value
  92. // used to determine a unique discovery strategy.
  93. DiscoveryValueHMACKey string
  94. // GeoIPDatabaseFilenames are paths of GeoIP2/GeoLite2
  95. // MaxMind database files. When empty, no GeoIP lookups are
  96. // performed. Each file is queried, in order, for the
  97. // logged fields: country code, city, and ISP. Multiple
  98. // file support accommodates the MaxMind distribution where
  99. // ISP data in a separate file.
  100. GeoIPDatabaseFilenames []string
  101. // PsinetDatabaseFilename is the path of the file containing
  102. // psinet.Database data.
  103. PsinetDatabaseFilename string
  104. // HostID identifies the server host; this value is included with all logs.
  105. HostID string
  106. // HostProvider identifies the server host provider; this value is
  107. // included with all logs and logged only when not blank.
  108. HostProvider string
  109. // ServerIPAddress is the public IP address of the server.
  110. ServerIPAddress string
  111. // TunnelProtocolPorts specifies which tunnel protocols to run
  112. // and which ports to listen on for each protocol. Valid tunnel
  113. // protocols include:
  114. // "SSH", "OSSH", "TLS-OSSH", "UNFRONTED-MEEK-OSSH", "UNFRONTED-MEEK-HTTPS-OSSH",
  115. // "UNFRONTED-MEEK-SESSION-TICKET-OSSH", "FRONTED-MEEK-OSSH",
  116. // "FRONTED-MEEK-QUIC-OSSH", "FRONTED-MEEK-HTTP-OSSH", "QUIC-OSSH",
  117. // "TAPDANCE-OSSH", "CONJURE-OSSH", and "SHADOWSOCKS-OSSH".
  118. TunnelProtocolPorts map[string]int
  119. // TunnelProtocolPassthroughAddresses specifies passthrough addresses to be
  120. // used for tunnel protocols configured in TunnelProtocolPorts. Passthrough
  121. // is a probing defense which relays all network traffic between a client and
  122. // the passthrough target when the client fails anti-probing tests.
  123. //
  124. // TunnelProtocolPassthroughAddresses is supported for:
  125. // "TLS-OSSH", "UNFRONTED-MEEK-HTTPS-OSSH",
  126. // "UNFRONTED-MEEK-SESSION-TICKET-OSSH", "UNFRONTED-MEEK-OSSH".
  127. TunnelProtocolPassthroughAddresses map[string]string
  128. // LegacyPassthrough indicates whether to expect legacy passthrough messages
  129. // from clients attempting to connect. This should be set for existing/legacy
  130. // passthrough servers only.
  131. LegacyPassthrough bool
  132. // EnableGQUIC indicates whether to enable legacy gQUIC QUIC-OSSH
  133. // versions, for backwards compatibility with all versions used by older
  134. // clients. Enabling gQUIC degrades the anti-probing stance of QUIC-OSSH,
  135. // as the legacy gQUIC stack will respond to probing packets.
  136. EnableGQUIC bool
  137. // SSHPrivateKey is the SSH host key. The same key is used for
  138. // all protocols, run by this server instance, which use SSH.
  139. SSHPrivateKey string
  140. // SSHServerVersion is the server version presented in the
  141. // identification string. The same value is used for all
  142. // protocols, run by this server instance, which use SSH.
  143. SSHServerVersion string
  144. // SSHUserName is the SSH user name to be presented by the
  145. // the tunnel-core client. The same value is used for all
  146. // protocols, run by this server instance, which use SSH.
  147. SSHUserName string
  148. // SSHPassword is the SSH password to be presented by the
  149. // the tunnel-core client. The same value is used for all
  150. // protocols, run by this server instance, which use SSH.
  151. SSHPassword string
  152. // SSHBeginHandshakeTimeoutMilliseconds specifies the timeout
  153. // for clients queueing to begin an SSH handshake. The default
  154. // is SSH_BEGIN_HANDSHAKE_TIMEOUT.
  155. SSHBeginHandshakeTimeoutMilliseconds *int
  156. // SSHHandshakeTimeoutMilliseconds specifies the timeout
  157. // before which a client must complete its handshake. The default
  158. // is SSH_HANDSHAKE_TIMEOUT.
  159. SSHHandshakeTimeoutMilliseconds *int
  160. // ObfuscatedSSHKey is the secret key for use in the Obfuscated
  161. // SSH protocol. The same secret key is used for all protocols,
  162. // run by this server instance, which use Obfuscated SSH.
  163. ObfuscatedSSHKey string
  164. // ShadowsocksKey is the secret key for use in the Shadowsocks
  165. // protocol.
  166. ShadowsocksKey string
  167. // MeekCookieEncryptionPrivateKey is the NaCl private key used
  168. // to decrypt meek cookie payload sent from clients. The same
  169. // key is used for all meek protocols run by this server instance.
  170. MeekCookieEncryptionPrivateKey string
  171. // MeekObfuscatedKey is the secret key used for obfuscating
  172. // meek cookies sent from clients. The same key is used for all
  173. // meek protocols run by this server instance.
  174. //
  175. // NOTE: this key is also used by the TLS-OSSH protocol, which allows
  176. // clients with legacy unfronted meek-https server entries, that have the
  177. // passthrough capability, to connect with TLS-OSSH to the servers
  178. // corresponding to those server entries, which now support TLS-OSSH by
  179. // demultiplexing meek-https and TLS-OSSH over the meek-https port.
  180. MeekObfuscatedKey string
  181. // MeekProhibitedHeaders is a list of HTTP headers to check for
  182. // in client requests. If one of these headers is found, the
  183. // request fails. This is used to defend against abuse.
  184. MeekProhibitedHeaders []string
  185. // MeekRequiredHeaders is a list of HTTP header names and values that must
  186. // appear in requests. This is used to defend against abuse.
  187. MeekRequiredHeaders map[string]string
  188. // MeekServerCertificate specifies an optional certificate to use for meek
  189. // servers, in place of the default, randomly generate certificate. When
  190. // specified, the corresponding private key must be supplied in
  191. // MeekServerPrivateKey. Any specified certificate is used for all meek
  192. // listeners.
  193. MeekServerCertificate string
  194. // MeekServerPrivateKey is the private key corresponding to the optional
  195. // MeekServerCertificate parameter.
  196. MeekServerPrivateKey string
  197. // MeekProxyForwardedForHeaders is a list of HTTP headers which
  198. // may be added by downstream HTTP proxies or CDNs in front
  199. // of clients. These headers supply the original client IP
  200. // address, which is geolocated for stats purposes. Headers
  201. // include, for example, X-Forwarded-For. The header's value
  202. // is assumed to be a comma delimted list of IP addresses where
  203. // the client IP is the first IP address in the list. Meek protocols
  204. // look for these headers and use the client IP address from
  205. // the header if any one is present and the value is a valid
  206. // IP address; otherwise the direct connection remote address is
  207. // used as the client IP.
  208. MeekProxyForwardedForHeaders []string
  209. // MeekTurnAroundTimeoutMilliseconds specifies the amount of time meek will
  210. // wait for downstream bytes before responding to a request. The default is
  211. // MEEK_DEFAULT_TURN_AROUND_TIMEOUT.
  212. MeekTurnAroundTimeoutMilliseconds *int
  213. // MeekExtendedTurnAroundTimeoutMilliseconds specifies the extended amount of
  214. // time meek will wait for downstream bytes, as long as bytes arrive every
  215. // MeekTurnAroundTimeoutMilliseconds, before responding to a request. The
  216. // default is MEEK_DEFAULT_EXTENDED_TURN_AROUND_TIMEOUT.
  217. MeekExtendedTurnAroundTimeoutMilliseconds *int
  218. // MeekSkipExtendedTurnAroundThresholdBytes specifies when to skip the
  219. // extended turn around. When the number of bytes received in the client
  220. // request meets the threshold, optimize for upstream flows with quicker
  221. // round trip turn arounds.
  222. MeekSkipExtendedTurnAroundThresholdBytes *int
  223. // MeekMaxSessionStalenessMilliseconds specifies the TTL for meek sessions.
  224. // The default is MEEK_DEFAULT_MAX_SESSION_STALENESS.
  225. MeekMaxSessionStalenessMilliseconds *int
  226. // MeekHTTPClientIOTimeoutMilliseconds specifies meek HTTP server I/O
  227. // timeouts. The default is MEEK_DEFAULT_HTTP_CLIENT_IO_TIMEOUT.
  228. MeekHTTPClientIOTimeoutMilliseconds *int
  229. // MeekFrontedHTTPClientIOTimeoutMilliseconds specifies meek HTTP server
  230. // I/O timeouts for fronted protocols. The default is
  231. // MEEK_DEFAULT_FRONTED_HTTP_CLIENT_IO_TIMEOUT.
  232. MeekFrontedHTTPClientIOTimeoutMilliseconds *int
  233. // MeekCachedResponseBufferSize is the size of a private,
  234. // fixed-size buffer allocated for every meek client. The buffer
  235. // is used to cache response payload, allowing the client to retry
  236. // fetching when a network connection is interrupted. This retry
  237. // makes the OSSH tunnel within meek resilient to interruptions
  238. // at the HTTP TCP layer.
  239. // Larger buffers increase resiliency to interruption, but consume
  240. // more memory as buffers as never freed. The maximum size of a
  241. // response payload is a function of client activity, network
  242. // throughput and throttling.
  243. // A default of 64K is used when MeekCachedResponseBufferSize is 0.
  244. MeekCachedResponseBufferSize int
  245. // MeekCachedResponsePoolBufferSize is the size of a fixed-size,
  246. // shared buffer used to temporarily extend a private buffer when
  247. // MeekCachedResponseBufferSize is insufficient. Shared buffers
  248. // allow some clients to successfully retry longer response payloads
  249. // without allocating large buffers for all clients.
  250. // A default of 64K is used when MeekCachedResponsePoolBufferSize
  251. // is 0.
  252. MeekCachedResponsePoolBufferSize int
  253. // MeekCachedResponsePoolBufferCount is the number of shared
  254. // buffers. Shared buffers are allocated on first use and remain
  255. // allocated, so shared buffer count * size is roughly the memory
  256. // overhead of this facility.
  257. // A default of 2048 is used when MeekCachedResponsePoolBufferCount
  258. // is 0.
  259. MeekCachedResponsePoolBufferCount int
  260. // MeekCachedResponsePoolBufferClientLimit is the maximum number of of
  261. // shared buffers a single client may consume at once. A default of 32 is
  262. // used when MeekCachedResponsePoolBufferClientLimit is 0.
  263. MeekCachedResponsePoolBufferClientLimit int
  264. // UDPInterceptUdpgwServerAddress specifies the network address of
  265. // a udpgw server which clients may be port forwarding to. When
  266. // specified, these TCP port forwards are intercepted and handled
  267. // directly by this server, which parses the SSH channel using the
  268. // udpgw protocol. Handling includes udpgw transparent DNS: tunneled
  269. // UDP DNS packets are rerouted to the host's DNS server.
  270. //
  271. // The intercept is applied before the port forward destination is
  272. // validated against SSH_DISALLOWED_PORT_FORWARD_HOSTS and
  273. // AllowTCPPorts. So the intercept address may be any otherwise
  274. // prohibited destination.
  275. UDPInterceptUdpgwServerAddress string
  276. // DNSResolverIPAddress specifies the IP address of a DNS server
  277. // to be used when "/etc/resolv.conf" doesn't exist or fails to
  278. // parse. When blank, "/etc/resolv.conf" must contain a usable
  279. // "nameserver" entry.
  280. DNSResolverIPAddress string
  281. // LoadMonitorPeriodSeconds indicates how frequently to log server
  282. // load information (number of connected clients per tunnel protocol,
  283. // number of running goroutines, amount of memory allocated, etc.)
  284. // The default, 0, disables load logging.
  285. LoadMonitorPeriodSeconds int
  286. // PeakUpstreamFailureRateMinimumSampleSize specifies the minimum number
  287. // of samples (e.g., upstream port forward attempts) that are required
  288. // before taking a failure rate snapshot which may be recorded as
  289. // peak_dns_failure_rate/peak_tcp_port_forward_failure_rate. The default
  290. // is PEAK_UPSTREAM_FAILURE_RATE_SAMPLE_SIZE.
  291. PeakUpstreamFailureRateMinimumSampleSize *int
  292. // ProcessProfileOutputDirectory is the path of a directory to which
  293. // process profiles will be written when signaled with SIGUSR2. The
  294. // files are overwritten on each invocation. When set to the default
  295. // value, blank, no profiles are written on SIGUSR2. Profiles include
  296. // the default profiles here: https://golang.org/pkg/runtime/pprof/#Profile.
  297. ProcessProfileOutputDirectory string
  298. // ProcessBlockProfileDurationSeconds specifies the sample duration for
  299. // "block" profiling. For the default, 0, no "block" profile is taken.
  300. ProcessBlockProfileDurationSeconds int
  301. // ProcessCPUProfileDurationSeconds specifies the sample duration for
  302. // CPU profiling. For the default, 0, no CPU profile is taken.
  303. ProcessCPUProfileDurationSeconds int
  304. // TrafficRulesFilename is the path of a file containing a JSON-encoded
  305. // TrafficRulesSet, the traffic rules to apply to Psiphon client tunnels.
  306. TrafficRulesFilename string
  307. // OSLConfigFilename is the path of a file containing a JSON-encoded
  308. // OSL Config, the OSL schemes to apply to Psiphon client tunnels.
  309. OSLConfigFilename string
  310. // RunPacketTunnel specifies whether to run a packet tunnel.
  311. RunPacketTunnel bool
  312. // PacketTunnelEgressInterface specifies tun.ServerConfig.EgressInterface.
  313. PacketTunnelEgressInterface string
  314. // PacketTunnelEnableDNSFlowTracking sets
  315. // tun.ServerConfig.EnableDNSFlowTracking.
  316. PacketTunnelEnableDNSFlowTracking bool
  317. // PacketTunnelDownstreamPacketQueueSize specifies
  318. // tun.ServerConfig.DownStreamPacketQueueSize.
  319. PacketTunnelDownstreamPacketQueueSize int
  320. // PacketTunnelSessionIdleExpirySeconds specifies
  321. // tun.ServerConfig.SessionIdleExpirySeconds.
  322. PacketTunnelSessionIdleExpirySeconds int
  323. // PacketTunnelSudoNetworkConfigCommands sets
  324. // tun.ServerConfig.SudoNetworkConfigCommands.
  325. PacketTunnelSudoNetworkConfigCommands bool
  326. // RunPacketManipulator specifies whether to run a packet manipulator.
  327. RunPacketManipulator bool
  328. // MaxConcurrentSSHHandshakes specifies a limit on the number of concurrent
  329. // SSH handshake negotiations. This is set to mitigate spikes in memory
  330. // allocations and CPU usage associated with SSH handshakes when many clients
  331. // attempt to connect concurrently. When a maximum limit is specified and
  332. // reached, additional clients that establish TCP or meek connections will
  333. // be disconnected after a short wait for the number of concurrent handshakes
  334. // to drop below the limit.
  335. // The default, 0 is no limit.
  336. MaxConcurrentSSHHandshakes int
  337. // PeriodicGarbageCollectionSeconds turns on periodic calls to
  338. // debug.FreeOSMemory, every specified number of seconds, to force garbage
  339. // collection and memory scavenging. Specify 0 to disable. The default is
  340. // PERIODIC_GARBAGE_COLLECTION.
  341. PeriodicGarbageCollectionSeconds *int
  342. // StopEstablishTunnelsEstablishedClientThreshold sets the established client
  343. // threshold for dumping profiles when SIGTSTP is signaled. When there are
  344. // less than or equal to the threshold number of established clients,
  345. // profiles are dumped to aid investigating unusual load limited states that
  346. // occur when few clients are connected and load should be relatively low. A
  347. // profile dump is attempted at most once per process lifetime, the first
  348. // time the threshold is met. Disabled when < 0.
  349. StopEstablishTunnelsEstablishedClientThreshold *int
  350. // AccessControlVerificationKeyRing is the access control authorization
  351. // verification key ring used to verify signed authorizations presented
  352. // by clients. Verified, active (unexpired) access control types will be
  353. // available for matching in the TrafficRulesFilter for the client via
  354. // AuthorizedAccessTypes. All other authorizations are ignored.
  355. AccessControlVerificationKeyRing accesscontrol.VerificationKeyRing
  356. // TacticsConfigFilename is the path of a file containing a JSON-encoded
  357. // tactics server configuration.
  358. TacticsConfigFilename string
  359. // BlocklistFilename is the path of a file containing a CSV-encoded
  360. // blocklist configuration. See NewBlocklist for more file format
  361. // documentation.
  362. BlocklistFilename string
  363. // BlocklistActive indicates whether to actively prevent blocklist hits in
  364. // addition to logging events.
  365. BlocklistActive bool
  366. // AllowBogons disables port forward bogon checks. This should be used only
  367. // for testing.
  368. AllowBogons bool
  369. // EnableSteeringIPs enables meek server steering IP support.
  370. EnableSteeringIPs bool
  371. // OwnEncodedServerEntries is a list of the server's own encoded server
  372. // entries, idenfified by server entry tag. These values are used in the
  373. // handshake API to update clients that don't yet have a signed copy of these
  374. // server entries.
  375. //
  376. // For purposes of compartmentalization, each server receives only its own
  377. // server entries here; and, besides the discovery server entries, in
  378. // psinet.Database, necessary for the discovery feature, no other server
  379. // entries are stored on a Psiphon server.
  380. OwnEncodedServerEntries map[string]string
  381. // MeekServerRunInproxyBroker indicates whether to run an in-proxy broker
  382. // endpoint and service under the meek server.
  383. MeekServerRunInproxyBroker bool
  384. // MeekServerInproxyBrokerOnly indicates whether to run only an in-proxy
  385. // broker under the meek server, and not run any meek tunnel protocol. To
  386. // run the meek listener, a meek server protocol and port must still be
  387. // specified in TunnelProtocolPorts, but no other tunnel protocol
  388. // parameters are required.
  389. MeekServerInproxyBrokerOnly bool
  390. // InproxyBrokerSessionPrivateKey specifies the broker's in-proxy session
  391. // private key and derived public key used by in-proxy clients and
  392. // proxies. This value is required when running an in-proxy broker.
  393. InproxyBrokerSessionPrivateKey string
  394. // InproxyBrokerObfuscationRootSecret specifies the broker's in-proxy
  395. // session root obfuscation secret used by in-proxy clients and proxies.
  396. // This value is required when running an in-proxy broker.
  397. InproxyBrokerObfuscationRootSecret string
  398. // InproxyBrokerServerEntrySignaturePublicKey specifies the public key
  399. // used to verify Psiphon server entry signature. This value is required
  400. // when running an in-proxy broker.
  401. InproxyBrokerServerEntrySignaturePublicKey string
  402. // InproxyBrokerAllowCommonASNMatching overrides the default broker
  403. // matching behavior which doesn't match non-personal in-proxy clients
  404. // and proxies from the same ASN. This parameter is for testing only.
  405. InproxyBrokerAllowCommonASNMatching bool
  406. // InproxyBrokerAllowBogonWebRTCConnections overrides the default broker
  407. // SDP validation behavior, which doesn't allow private network WebRTC
  408. // candidates. This parameter is for testing only.
  409. InproxyBrokerAllowBogonWebRTCConnections bool
  410. // InproxyServerSessionPrivateKey specifies the server's in-proxy session
  411. // private key and derived public key used by brokers. This value is
  412. // required when running in-proxy tunnel protocols.
  413. InproxyServerSessionPrivateKey string
  414. // InproxyServerObfuscationRootSecret specifies the server's in-proxy
  415. // session root obfuscation secret used by brokers. This value is
  416. // required when running in-proxy tunnel protocols.
  417. InproxyServerObfuscationRootSecret string
  418. sshBeginHandshakeTimeout time.Duration
  419. sshHandshakeTimeout time.Duration
  420. peakUpstreamFailureRateMinimumSampleSize int
  421. periodicGarbageCollection time.Duration
  422. stopEstablishTunnelsEstablishedClientThreshold int
  423. dumpProfilesOnStopEstablishTunnelsDoneOnce int32
  424. providerID string
  425. frontingProviderID string
  426. region string
  427. runningProtocols []string
  428. runningOnlyInproxyBroker bool
  429. }
  430. // GetLogFileReopenConfig gets the reopen retries, and create/mode inputs for
  431. // rotate.NewRotatableFileWriter, which is used when writing to log files.
  432. //
  433. // By default, we expect the log files to be managed by logrotate, with
  434. // logrotate configured to re-create the next log file after rotation. As
  435. // described in the documentation for rotate.NewRotatableFileWriter, and as
  436. // observed in production, we occasionally need retries when attempting to
  437. // reopen the log file post-rotation; and we avoid conflicts, and spurious
  438. // re-rotations, by disabling file create in rotate.NewRotatableFileWriter. In
  439. // large scale production, incidents requiring retry are very rare, so the
  440. // retry delay is not expected to have a significant impact on performance.
  441. //
  442. // The defaults may be overriden in the Config.
  443. func (config *Config) GetLogFileReopenConfig() (int, bool, os.FileMode) {
  444. retries := DEFAULT_LOG_FILE_REOPEN_RETRIES
  445. if config.LogFileReopenRetries != nil {
  446. retries = *config.LogFileReopenRetries
  447. }
  448. create := false
  449. mode := os.FileMode(0)
  450. if config.LogFileCreateMode != nil {
  451. create = true
  452. mode = os.FileMode(*config.LogFileCreateMode)
  453. }
  454. return retries, create, mode
  455. }
  456. // RunLoadMonitor indicates whether to monitor and log server load.
  457. func (config *Config) RunLoadMonitor() bool {
  458. return config.LoadMonitorPeriodSeconds > 0
  459. }
  460. // RunPeriodicGarbageCollection indicates whether to run periodic garbage collection.
  461. func (config *Config) RunPeriodicGarbageCollection() bool {
  462. return config.periodicGarbageCollection > 0
  463. }
  464. // DumpProfilesOnStopEstablishTunnels indicates whether dump profiles due to
  465. // an unexpectedly low number of established clients during high load.
  466. func (config *Config) DumpProfilesOnStopEstablishTunnels(establishedClientsCount int) bool {
  467. if config.stopEstablishTunnelsEstablishedClientThreshold < 0 {
  468. return false
  469. }
  470. if config.runningOnlyInproxyBroker {
  471. // There will always be zero established clients when running only the
  472. // in-proxy broker and no tunnel protocols.
  473. return false
  474. }
  475. if atomic.LoadInt32(&config.dumpProfilesOnStopEstablishTunnelsDoneOnce) != 0 {
  476. return false
  477. }
  478. dump := (establishedClientsCount <= config.stopEstablishTunnelsEstablishedClientThreshold)
  479. if dump {
  480. atomic.StoreInt32(&config.dumpProfilesOnStopEstablishTunnelsDoneOnce, 1)
  481. }
  482. return dump
  483. }
  484. // GetOwnEncodedServerEntry returns one of the server's own server entries, as
  485. // identified by the server entry tag.
  486. func (config *Config) GetOwnEncodedServerEntry(serverEntryTag string) (string, bool) {
  487. serverEntry, ok := config.OwnEncodedServerEntries[serverEntryTag]
  488. return serverEntry, ok
  489. }
  490. // GetProviderID returns the provider ID associated with the server.
  491. func (config *Config) GetProviderID() string {
  492. return config.providerID
  493. }
  494. // GetFrontingProviderID returns the fronting provider ID associated with the
  495. // server's fronted protocol(s).
  496. func (config *Config) GetFrontingProviderID() string {
  497. return config.frontingProviderID
  498. }
  499. // GetRegion returns the region associated with the server.
  500. func (config *Config) GetRegion() string {
  501. return config.region
  502. }
  503. // GetRunningProtocols returns the list of protcols this server is running.
  504. // The caller must not mutate the return value.
  505. func (config *Config) GetRunningProtocols() []string {
  506. return config.runningProtocols
  507. }
  508. // GetRunningOnlyInproxyBroker indicates if the server is running only the
  509. // in-proxy broker and no tunnel protocols.
  510. func (config *Config) GetRunningOnlyInproxyBroker() bool {
  511. return config.runningOnlyInproxyBroker
  512. }
  513. // LoadConfig loads and validates a JSON encoded server config.
  514. func LoadConfig(configJSON []byte) (*Config, error) {
  515. var config Config
  516. err := json.Unmarshal(configJSON, &config)
  517. if err != nil {
  518. return nil, errors.Trace(err)
  519. }
  520. if config.ServerIPAddress == "" {
  521. return nil, errors.TraceNew("ServerIPAddress is required")
  522. }
  523. if config.MeekServerRunInproxyBroker {
  524. if config.InproxyBrokerSessionPrivateKey == "" {
  525. return nil, errors.TraceNew("Inproxy Broker requires InproxyBrokerSessionPrivateKey")
  526. }
  527. if config.InproxyBrokerObfuscationRootSecret == "" {
  528. return nil, errors.TraceNew("Inproxy Broker requires InproxyBrokerObfuscationRootSecret")
  529. }
  530. // There must be at least one meek tunnel protocol configured for
  531. // MeekServer to run and host an in-proxy broker. Since each
  532. // MeekServer instance runs its own in-proxy Broker instance, allow
  533. // at most one meek tunnel protocol to be configured so all
  534. // connections to the broker use the same, unambiguous instance.
  535. meekServerCount := 0
  536. for tunnelProtocol := range config.TunnelProtocolPorts {
  537. if protocol.TunnelProtocolUsesMeek(tunnelProtocol) {
  538. meekServerCount += 1
  539. }
  540. }
  541. if meekServerCount != 1 {
  542. return nil, errors.TraceNew("Inproxy Broker requires one MeekServer instance")
  543. }
  544. }
  545. if config.MeekServerInproxyBrokerOnly {
  546. if !config.MeekServerRunInproxyBroker {
  547. return nil, errors.TraceNew("Inproxy Broker-only mode requires MeekServerRunInproxyBroker")
  548. }
  549. }
  550. config.runningProtocols = []string{}
  551. config.runningOnlyInproxyBroker = config.MeekServerRunInproxyBroker
  552. for tunnelProtocol := range config.TunnelProtocolPorts {
  553. if !common.Contains(protocol.SupportedTunnelProtocols, tunnelProtocol) {
  554. return nil, errors.Tracef("Unsupported tunnel protocol: %s", tunnelProtocol)
  555. }
  556. if config.MeekServerInproxyBrokerOnly && protocol.TunnelProtocolUsesMeek(tunnelProtocol) {
  557. // In in-proxy broker-only mode, the TunnelProtocolPorts must be
  558. // specified in order to run the MeekServer, but none of the
  559. // following meek tunnel parameters are required.
  560. continue
  561. }
  562. if protocol.TunnelProtocolUsesInproxy(tunnelProtocol) && !inproxy.Enabled() {
  563. // Note that, technically, it may be possible to allow this case,
  564. // since PSIPHON_ENABLE_INPROXY is currently required only for
  565. // client/proxy-side WebRTC functionality, although that could change.
  566. return nil, errors.TraceNew("inproxy implementation is not enabled")
  567. }
  568. if protocol.TunnelProtocolUsesSSH(tunnelProtocol) ||
  569. protocol.TunnelProtocolUsesObfuscatedSSH(tunnelProtocol) {
  570. if config.SSHPrivateKey == "" || config.SSHServerVersion == "" ||
  571. config.SSHUserName == "" || config.SSHPassword == "" {
  572. return nil, errors.Tracef(
  573. "Tunnel protocol %s requires SSHPrivateKey, SSHServerVersion, SSHUserName, SSHPassword",
  574. tunnelProtocol)
  575. }
  576. }
  577. if protocol.TunnelProtocolUsesObfuscatedSSH(tunnelProtocol) {
  578. if config.ObfuscatedSSHKey == "" {
  579. return nil, errors.Tracef(
  580. "Tunnel protocol %s requires ObfuscatedSSHKey",
  581. tunnelProtocol)
  582. }
  583. }
  584. if protocol.TunnelProtocolUsesTLSOSSH(tunnelProtocol) {
  585. // Meek obfuscated key used for legacy reasons. See comment for
  586. // MeekObfuscatedKey.
  587. if config.MeekObfuscatedKey == "" {
  588. return nil, errors.Tracef(
  589. "Tunnel protocol %s requires MeekObfuscatedKey",
  590. tunnelProtocol)
  591. }
  592. }
  593. if protocol.TunnelProtocolUsesMeekHTTP(tunnelProtocol) ||
  594. protocol.TunnelProtocolUsesMeekHTTPS(tunnelProtocol) {
  595. if config.MeekCookieEncryptionPrivateKey == "" || config.MeekObfuscatedKey == "" {
  596. return nil, errors.Tracef(
  597. "Tunnel protocol %s requires MeekCookieEncryptionPrivateKey, MeekObfuscatedKey",
  598. tunnelProtocol)
  599. }
  600. }
  601. // For FRONTED QUIC and HTTP, HTTPS is always used on the
  602. // edge-to-server hop, so it must be enabled or else this
  603. // configuration will not work. There is no FRONTED QUIC listener at
  604. // all; see TunnelServer.Run.
  605. if protocol.TunnelProtocolUsesFrontedMeek(tunnelProtocol) {
  606. _, ok := config.TunnelProtocolPorts[protocol.TUNNEL_PROTOCOL_FRONTED_MEEK]
  607. if !ok {
  608. return nil, errors.Tracef(
  609. "Tunnel protocol %s requires %s to be enabled",
  610. tunnelProtocol,
  611. protocol.TUNNEL_PROTOCOL_FRONTED_MEEK)
  612. }
  613. }
  614. config.runningProtocols = append(config.runningProtocols, tunnelProtocol)
  615. config.runningOnlyInproxyBroker = false
  616. }
  617. for tunnelProtocol, address := range config.TunnelProtocolPassthroughAddresses {
  618. if !protocol.TunnelProtocolSupportsPassthrough(tunnelProtocol) {
  619. return nil, errors.Tracef("Passthrough unsupported tunnel protocol: %s", tunnelProtocol)
  620. }
  621. if _, _, err := net.SplitHostPort(address); err != nil {
  622. if err != nil {
  623. return nil, errors.Tracef(
  624. "Tunnel protocol %s passthrough address %s invalid: %s",
  625. tunnelProtocol, address, err)
  626. }
  627. }
  628. }
  629. config.sshBeginHandshakeTimeout = SSH_BEGIN_HANDSHAKE_TIMEOUT
  630. if config.SSHBeginHandshakeTimeoutMilliseconds != nil {
  631. config.sshBeginHandshakeTimeout = time.Duration(*config.SSHBeginHandshakeTimeoutMilliseconds) * time.Millisecond
  632. }
  633. config.sshHandshakeTimeout = SSH_HANDSHAKE_TIMEOUT
  634. if config.SSHHandshakeTimeoutMilliseconds != nil {
  635. config.sshHandshakeTimeout = time.Duration(*config.SSHHandshakeTimeoutMilliseconds) * time.Millisecond
  636. }
  637. if config.ObfuscatedSSHKey != "" {
  638. seed, err := protocol.DeriveSSHServerVersionPRNGSeed(config.ObfuscatedSSHKey)
  639. if err != nil {
  640. return nil, errors.Tracef(
  641. "DeriveSSHServerVersionPRNGSeed failed: %s", err)
  642. }
  643. serverVersion := values.GetSSHServerVersion(seed)
  644. if serverVersion != "" {
  645. config.SSHServerVersion = serverVersion
  646. }
  647. }
  648. if config.UDPInterceptUdpgwServerAddress != "" {
  649. if err := validateNetworkAddress(config.UDPInterceptUdpgwServerAddress, true); err != nil {
  650. return nil, errors.Tracef("UDPInterceptUdpgwServerAddress is invalid: %s", err)
  651. }
  652. }
  653. if config.DNSResolverIPAddress != "" {
  654. if net.ParseIP(config.DNSResolverIPAddress) == nil {
  655. return nil, errors.Tracef("DNSResolverIPAddress is invalid")
  656. }
  657. }
  658. config.peakUpstreamFailureRateMinimumSampleSize = PEAK_UPSTREAM_FAILURE_RATE_MINIMUM_SAMPLE_SIZE
  659. if config.PeakUpstreamFailureRateMinimumSampleSize != nil {
  660. config.peakUpstreamFailureRateMinimumSampleSize = *config.PeakUpstreamFailureRateMinimumSampleSize
  661. }
  662. config.periodicGarbageCollection = PERIODIC_GARBAGE_COLLECTION
  663. if config.PeriodicGarbageCollectionSeconds != nil {
  664. config.periodicGarbageCollection = time.Duration(*config.PeriodicGarbageCollectionSeconds) * time.Second
  665. }
  666. config.stopEstablishTunnelsEstablishedClientThreshold = STOP_ESTABLISH_TUNNELS_ESTABLISHED_CLIENT_THRESHOLD
  667. if config.StopEstablishTunnelsEstablishedClientThreshold != nil {
  668. config.stopEstablishTunnelsEstablishedClientThreshold = *config.StopEstablishTunnelsEstablishedClientThreshold
  669. }
  670. err = accesscontrol.ValidateVerificationKeyRing(&config.AccessControlVerificationKeyRing)
  671. if err != nil {
  672. return nil, errors.Tracef(
  673. "AccessControlVerificationKeyRing is invalid: %s", err)
  674. }
  675. // Limitation: the following is a shortcut which extracts the server's
  676. // fronting provider ID from the server's OwnEncodedServerEntries. This logic
  677. // assumes a server has only one fronting provider. In principle, it's
  678. // possible for server with multiple server entries to run multiple fronted
  679. // protocols, each with a different fronting provider ID.
  680. //
  681. // TODO: add an explicit parameter mapping tunnel protocol ports to fronting
  682. // provider IDs.
  683. for _, encodedServerEntry := range config.OwnEncodedServerEntries {
  684. serverEntry, err := protocol.DecodeServerEntry(encodedServerEntry, "", "")
  685. if err != nil {
  686. return nil, errors.Tracef(
  687. "protocol.DecodeServerEntry failed: %s", err)
  688. }
  689. if config.providerID == "" {
  690. config.providerID = serverEntry.ProviderID
  691. } else if config.providerID != serverEntry.ProviderID {
  692. return nil, errors.Tracef("unsupported multiple ProviderID values")
  693. }
  694. if config.frontingProviderID == "" {
  695. config.frontingProviderID = serverEntry.FrontingProviderID
  696. } else if config.frontingProviderID != serverEntry.FrontingProviderID {
  697. return nil, errors.Tracef("unsupported multiple FrontingProviderID values")
  698. }
  699. if config.region == "" {
  700. config.region = serverEntry.Region
  701. } else if config.region != serverEntry.Region {
  702. return nil, errors.Tracef("unsupported multiple Region values")
  703. }
  704. }
  705. return &config, nil
  706. }
  707. func validateNetworkAddress(address string, requireIPaddress bool) error {
  708. host, portStr, err := net.SplitHostPort(address)
  709. if err != nil {
  710. return err
  711. }
  712. if requireIPaddress && net.ParseIP(host) == nil {
  713. return errors.TraceNew("host must be an IP address")
  714. }
  715. port, err := strconv.Atoi(portStr)
  716. if err != nil {
  717. return err
  718. }
  719. if port < 0 || port > 65535 {
  720. return errors.TraceNew("invalid port")
  721. }
  722. return nil
  723. }
  724. // GenerateConfigParams specifies customizations to be applied to
  725. // a generated server config.
  726. type GenerateConfigParams struct {
  727. LogFilename string
  728. SkipPanickingLogWriter bool
  729. LogLevel string
  730. ServerEntrySignaturePublicKey string
  731. ServerEntrySignaturePrivateKey string
  732. ServerIPAddress string
  733. TunnelProtocolPorts map[string]int
  734. TunnelProtocolPassthroughAddresses map[string]string
  735. TrafficRulesConfigFilename string
  736. OSLConfigFilename string
  737. TacticsConfigFilename string
  738. TacticsRequestPublicKey string
  739. TacticsRequestObfuscatedKey string
  740. Passthrough bool
  741. LegacyPassthrough bool
  742. LimitQUICVersions protocol.QUICVersions
  743. EnableGQUIC bool
  744. FrontingProviderID string
  745. }
  746. // GenerateConfig creates a new Psiphon server config. It returns JSON encoded
  747. // configs and a client-compatible "server entry" for the server. It generates
  748. // all necessary secrets and key material, which are emitted in the config
  749. // file and server entry as necessary.
  750. //
  751. // GenerateConfig uses sample values for many fields. The intention is for
  752. // generated configs to be used for testing or as examples for production
  753. // setup, not to generate production-ready configurations.
  754. //
  755. // When tactics key material is provided in GenerateConfigParams, tactics
  756. // capabilities are added for all meek protocols in TunnelProtocolPorts.
  757. func GenerateConfig(params *GenerateConfigParams) ([]byte, []byte, []byte, []byte, []byte, error) {
  758. // Input validation
  759. if net.ParseIP(params.ServerIPAddress) == nil {
  760. return nil, nil, nil, nil, nil, errors.TraceNew("invalid IP address")
  761. }
  762. if len(params.TunnelProtocolPorts) == 0 {
  763. return nil, nil, nil, nil, nil, errors.TraceNew("no tunnel protocols")
  764. }
  765. usedPort := make(map[int]bool)
  766. usingMeek := false
  767. usingTLSOSSH := false
  768. usingInproxy := false
  769. for tunnelProtocol, port := range params.TunnelProtocolPorts {
  770. if !common.Contains(protocol.SupportedTunnelProtocols, tunnelProtocol) {
  771. return nil, nil, nil, nil, nil, errors.TraceNew("invalid tunnel protocol")
  772. }
  773. if usedPort[port] {
  774. return nil, nil, nil, nil, nil, errors.TraceNew("duplicate listening port")
  775. }
  776. usedPort[port] = true
  777. if protocol.TunnelProtocolUsesTLSOSSH(tunnelProtocol) {
  778. usingTLSOSSH = true
  779. }
  780. if protocol.TunnelProtocolUsesMeekHTTP(tunnelProtocol) ||
  781. protocol.TunnelProtocolUsesMeekHTTPS(tunnelProtocol) {
  782. usingMeek = true
  783. }
  784. if protocol.TunnelProtocolUsesInproxy(tunnelProtocol) {
  785. usingInproxy = true
  786. }
  787. }
  788. // One test mode populates the tactics config file; this will generate
  789. // keys. Another test mode passes in existing keys to be used in the
  790. // server entry. Both the filename and existing keys cannot be passed in.
  791. if (params.TacticsConfigFilename != "") &&
  792. (params.TacticsRequestPublicKey != "" || params.TacticsRequestObfuscatedKey != "") {
  793. return nil, nil, nil, nil, nil, errors.TraceNew("invalid tactics parameters")
  794. }
  795. // SSH config
  796. rsaKey, err := rsa.GenerateKey(rand.Reader, SSH_RSA_HOST_KEY_BITS)
  797. if err != nil {
  798. return nil, nil, nil, nil, nil, errors.Trace(err)
  799. }
  800. sshPrivateKey := pem.EncodeToMemory(
  801. &pem.Block{
  802. Type: "RSA PRIVATE KEY",
  803. Bytes: x509.MarshalPKCS1PrivateKey(rsaKey),
  804. },
  805. )
  806. signer, err := ssh.NewSignerFromKey(rsaKey)
  807. if err != nil {
  808. return nil, nil, nil, nil, nil, errors.Trace(err)
  809. }
  810. sshPublicKey := signer.PublicKey()
  811. sshUserNameSuffixBytes, err := common.MakeSecureRandomBytes(SSH_USERNAME_SUFFIX_BYTE_LENGTH)
  812. if err != nil {
  813. return nil, nil, nil, nil, nil, errors.Trace(err)
  814. }
  815. sshUserNameSuffix := hex.EncodeToString(sshUserNameSuffixBytes)
  816. sshUserName := "psiphon_" + sshUserNameSuffix
  817. sshPasswordBytes, err := common.MakeSecureRandomBytes(SSH_PASSWORD_BYTE_LENGTH)
  818. if err != nil {
  819. return nil, nil, nil, nil, nil, errors.Trace(err)
  820. }
  821. sshPassword := hex.EncodeToString(sshPasswordBytes)
  822. sshServerVersion := "SSH-2.0-Psiphon"
  823. // Obfuscated SSH config
  824. obfuscatedSSHKeyBytes, err := common.MakeSecureRandomBytes(SSH_OBFUSCATED_KEY_BYTE_LENGTH)
  825. if err != nil {
  826. return nil, nil, nil, nil, nil, errors.Trace(err)
  827. }
  828. obfuscatedSSHKey := hex.EncodeToString(obfuscatedSSHKeyBytes)
  829. // Shadowsocks config
  830. shadowsocksKeyBytes, err := common.MakeSecureRandomBytes(SHADOWSOCKS_KEY_BYTE_LENGTH)
  831. if err != nil {
  832. return nil, nil, nil, nil, nil, errors.Trace(err)
  833. }
  834. shadowsocksKey := hex.EncodeToString(shadowsocksKeyBytes)
  835. // Meek config
  836. var meekCookieEncryptionPublicKey, meekCookieEncryptionPrivateKey, meekObfuscatedKey string
  837. if usingMeek {
  838. rawMeekCookieEncryptionPublicKey, rawMeekCookieEncryptionPrivateKey, err :=
  839. box.GenerateKey(rand.Reader)
  840. if err != nil {
  841. return nil, nil, nil, nil, nil, errors.Trace(err)
  842. }
  843. meekCookieEncryptionPublicKey = base64.StdEncoding.EncodeToString(rawMeekCookieEncryptionPublicKey[:])
  844. meekCookieEncryptionPrivateKey = base64.StdEncoding.EncodeToString(rawMeekCookieEncryptionPrivateKey[:])
  845. }
  846. if usingMeek || usingTLSOSSH {
  847. meekObfuscatedKeyBytes, err := common.MakeSecureRandomBytes(SSH_OBFUSCATED_KEY_BYTE_LENGTH)
  848. if err != nil {
  849. return nil, nil, nil, nil, nil, errors.Trace(err)
  850. }
  851. meekObfuscatedKey = hex.EncodeToString(meekObfuscatedKeyBytes)
  852. }
  853. // Inproxy config
  854. var inproxyServerSessionPublicKey,
  855. inproxyServerSessionPrivateKey,
  856. inproxyServerObfuscationRootSecret string
  857. if usingInproxy {
  858. privateKey, err := inproxy.GenerateSessionPrivateKey()
  859. if err != nil {
  860. return nil, nil, nil, nil, nil, errors.Trace(err)
  861. }
  862. inproxyServerSessionPrivateKey = privateKey.String()
  863. publicKey, err := privateKey.GetPublicKey()
  864. if err != nil {
  865. return nil, nil, nil, nil, nil, errors.Trace(err)
  866. }
  867. inproxyServerSessionPublicKey = publicKey.String()
  868. obfuscationRootSecret, err := inproxy.GenerateRootObfuscationSecret()
  869. if err != nil {
  870. return nil, nil, nil, nil, nil, errors.Trace(err)
  871. }
  872. inproxyServerObfuscationRootSecret = obfuscationRootSecret.String()
  873. }
  874. // Other config
  875. discoveryValueHMACKeyBytes, err := common.MakeSecureRandomBytes(DISCOVERY_VALUE_KEY_BYTE_LENGTH)
  876. if err != nil {
  877. return nil, nil, nil, nil, nil, errors.Trace(err)
  878. }
  879. discoveryValueHMACKey := base64.StdEncoding.EncodeToString(discoveryValueHMACKeyBytes)
  880. // Generate a legacy web server secret, to accomodate test cases, such as deriving
  881. // a server entry tag when no tag is present.
  882. webServerSecretBytes, err := common.MakeSecureRandomBytes(WEB_SERVER_SECRET_BYTE_LENGTH)
  883. if err != nil {
  884. return nil, nil, nil, nil, nil, errors.Trace(err)
  885. }
  886. webServerSecret := hex.EncodeToString(webServerSecretBytes)
  887. // Assemble configs and server entry
  888. // Note: this config is intended for either testing or as an illustrative
  889. // example or template and is not intended for production deployment.
  890. logLevel := params.LogLevel
  891. if logLevel == "" {
  892. logLevel = "info"
  893. }
  894. // For testing, set the Psiphon server to create its log files; we do not
  895. // expect tests to necessarily run under log managers, such as logrotate.
  896. createMode := 0666
  897. config := &Config{
  898. LogLevel: logLevel,
  899. LogFilename: params.LogFilename,
  900. LogFileCreateMode: &createMode,
  901. SkipPanickingLogWriter: params.SkipPanickingLogWriter,
  902. GeoIPDatabaseFilenames: nil,
  903. HostID: "example-host-id",
  904. ServerIPAddress: params.ServerIPAddress,
  905. DiscoveryValueHMACKey: discoveryValueHMACKey,
  906. SSHPrivateKey: string(sshPrivateKey),
  907. SSHServerVersion: sshServerVersion,
  908. SSHUserName: sshUserName,
  909. SSHPassword: sshPassword,
  910. ShadowsocksKey: shadowsocksKey,
  911. ObfuscatedSSHKey: obfuscatedSSHKey,
  912. TunnelProtocolPorts: params.TunnelProtocolPorts,
  913. TunnelProtocolPassthroughAddresses: params.TunnelProtocolPassthroughAddresses,
  914. DNSResolverIPAddress: "8.8.8.8",
  915. UDPInterceptUdpgwServerAddress: "127.0.0.1:7300",
  916. MeekCookieEncryptionPrivateKey: meekCookieEncryptionPrivateKey,
  917. MeekObfuscatedKey: meekObfuscatedKey,
  918. MeekProhibitedHeaders: nil,
  919. MeekProxyForwardedForHeaders: []string{"X-Forwarded-For"},
  920. LoadMonitorPeriodSeconds: 300,
  921. TrafficRulesFilename: params.TrafficRulesConfigFilename,
  922. OSLConfigFilename: params.OSLConfigFilename,
  923. TacticsConfigFilename: params.TacticsConfigFilename,
  924. LegacyPassthrough: params.LegacyPassthrough,
  925. EnableGQUIC: params.EnableGQUIC,
  926. InproxyServerSessionPrivateKey: inproxyServerSessionPrivateKey,
  927. InproxyServerObfuscationRootSecret: inproxyServerObfuscationRootSecret,
  928. }
  929. encodedConfig, err := json.MarshalIndent(config, "\n", " ")
  930. if err != nil {
  931. return nil, nil, nil, nil, nil, errors.Trace(err)
  932. }
  933. intPtr := func(i int) *int {
  934. return &i
  935. }
  936. trafficRulesSet := &TrafficRulesSet{
  937. DefaultRules: TrafficRules{
  938. RateLimits: RateLimits{
  939. ReadUnthrottledBytes: new(int64),
  940. ReadBytesPerSecond: new(int64),
  941. WriteUnthrottledBytes: new(int64),
  942. WriteBytesPerSecond: new(int64),
  943. },
  944. IdleTCPPortForwardTimeoutMilliseconds: intPtr(DEFAULT_IDLE_TCP_PORT_FORWARD_TIMEOUT_MILLISECONDS),
  945. IdleUDPPortForwardTimeoutMilliseconds: intPtr(DEFAULT_IDLE_UDP_PORT_FORWARD_TIMEOUT_MILLISECONDS),
  946. MaxTCPPortForwardCount: intPtr(DEFAULT_MAX_TCP_PORT_FORWARD_COUNT),
  947. MaxUDPPortForwardCount: intPtr(DEFAULT_MAX_UDP_PORT_FORWARD_COUNT),
  948. AllowTCPPorts: nil,
  949. AllowUDPPorts: nil,
  950. },
  951. }
  952. encodedTrafficRulesSet, err := json.MarshalIndent(trafficRulesSet, "\n", " ")
  953. if err != nil {
  954. return nil, nil, nil, nil, nil, errors.Trace(err)
  955. }
  956. encodedOSLConfig, err := json.MarshalIndent(&osl.Config{}, "\n", " ")
  957. if err != nil {
  958. return nil, nil, nil, nil, nil, errors.Trace(err)
  959. }
  960. tacticsRequestPublicKey := params.TacticsRequestPublicKey
  961. tacticsRequestObfuscatedKey := params.TacticsRequestObfuscatedKey
  962. var tacticsRequestPrivateKey string
  963. var encodedTacticsConfig []byte
  964. if params.TacticsConfigFilename != "" {
  965. tacticsRequestPublicKey, tacticsRequestPrivateKey, tacticsRequestObfuscatedKey, err =
  966. tactics.GenerateKeys()
  967. if err != nil {
  968. return nil, nil, nil, nil, nil, errors.Trace(err)
  969. }
  970. decodedTacticsRequestPublicKey, err := base64.StdEncoding.DecodeString(tacticsRequestPublicKey)
  971. if err != nil {
  972. return nil, nil, nil, nil, nil, errors.Trace(err)
  973. }
  974. decodedTacticsRequestPrivateKey, err := base64.StdEncoding.DecodeString(tacticsRequestPrivateKey)
  975. if err != nil {
  976. return nil, nil, nil, nil, nil, errors.Trace(err)
  977. }
  978. decodedTacticsRequestObfuscatedKey, err := base64.StdEncoding.DecodeString(tacticsRequestObfuscatedKey)
  979. if err != nil {
  980. return nil, nil, nil, nil, nil, errors.Trace(err)
  981. }
  982. tacticsConfig := &tactics.Server{
  983. RequestPublicKey: decodedTacticsRequestPublicKey,
  984. RequestPrivateKey: decodedTacticsRequestPrivateKey,
  985. RequestObfuscatedKey: decodedTacticsRequestObfuscatedKey,
  986. DefaultTactics: tactics.Tactics{
  987. TTL: "1m",
  988. },
  989. }
  990. encodedTacticsConfig, err = json.MarshalIndent(tacticsConfig, "\n", " ")
  991. if err != nil {
  992. return nil, nil, nil, nil, nil, errors.Trace(err)
  993. }
  994. }
  995. // Capabilities
  996. capabilities := []string{protocol.CAPABILITY_SSH_API_REQUESTS}
  997. var frontingProviderID string
  998. for tunnelProtocol := range params.TunnelProtocolPorts {
  999. capability := protocol.GetCapability(tunnelProtocol)
  1000. // In-proxy tunnel protocol capabilities don't include
  1001. // v1/-PASSTHROUGHv2 suffixes; see comments in ServerEntry.hasCapability.
  1002. if !protocol.TunnelProtocolUsesInproxy(tunnelProtocol) {
  1003. // Note: do not add passthrough annotation if HTTP unfronted meek
  1004. // because it would result in an invalid capability.
  1005. if params.Passthrough &&
  1006. protocol.TunnelProtocolSupportsPassthrough(tunnelProtocol) &&
  1007. tunnelProtocol != protocol.TUNNEL_PROTOCOL_UNFRONTED_MEEK {
  1008. if !params.LegacyPassthrough {
  1009. capability += "-PASSTHROUGH-v2"
  1010. } else {
  1011. capability += "-PASSTHROUGH"
  1012. }
  1013. }
  1014. if tunnelProtocol == protocol.TUNNEL_PROTOCOL_QUIC_OBFUSCATED_SSH &&
  1015. !params.EnableGQUIC {
  1016. capability += "v1"
  1017. }
  1018. }
  1019. capabilities = append(capabilities, capability)
  1020. if params.TacticsRequestPublicKey != "" && params.TacticsRequestObfuscatedKey != "" &&
  1021. protocol.TunnelProtocolSupportsTactics(tunnelProtocol) {
  1022. capabilities = append(capabilities, protocol.GetTacticsCapability(tunnelProtocol))
  1023. }
  1024. if protocol.TunnelProtocolUsesFrontedMeek(tunnelProtocol) {
  1025. frontingProviderID = params.FrontingProviderID
  1026. }
  1027. }
  1028. // Tunnel protocol ports
  1029. // Limitations:
  1030. // - Only one meek port may be specified per server entry.
  1031. // - Neither fronted meek nor Conjuure protocols are supported here.
  1032. var sshPort, obfuscatedSSHPort, meekPort, obfuscatedSSHQUICPort, tlsOSSHPort, shadowsocksPort int
  1033. var inproxySSHPort, inproxyOSSHPort, inproxyQUICPort, inproxyMeekPort, inproxyTlsOSSHPort, inproxyShadowsocksPort int
  1034. for tunnelProtocol, port := range params.TunnelProtocolPorts {
  1035. if !protocol.TunnelProtocolUsesInproxy(tunnelProtocol) {
  1036. switch tunnelProtocol {
  1037. case protocol.TUNNEL_PROTOCOL_TLS_OBFUSCATED_SSH:
  1038. tlsOSSHPort = port
  1039. case protocol.TUNNEL_PROTOCOL_SSH:
  1040. sshPort = port
  1041. case protocol.TUNNEL_PROTOCOL_OBFUSCATED_SSH:
  1042. obfuscatedSSHPort = port
  1043. case protocol.TUNNEL_PROTOCOL_QUIC_OBFUSCATED_SSH:
  1044. obfuscatedSSHQUICPort = port
  1045. case protocol.TUNNEL_PROTOCOL_UNFRONTED_MEEK_HTTPS,
  1046. protocol.TUNNEL_PROTOCOL_UNFRONTED_MEEK_SESSION_TICKET,
  1047. protocol.TUNNEL_PROTOCOL_UNFRONTED_MEEK:
  1048. meekPort = port
  1049. case protocol.TUNNEL_PROTOCOL_SHADOWSOCKS_OSSH:
  1050. shadowsocksPort = port
  1051. }
  1052. } else {
  1053. switch protocol.TunnelProtocolMinusInproxy(tunnelProtocol) {
  1054. case protocol.TUNNEL_PROTOCOL_TLS_OBFUSCATED_SSH:
  1055. inproxyTlsOSSHPort = port
  1056. case protocol.TUNNEL_PROTOCOL_SSH:
  1057. inproxySSHPort = port
  1058. case protocol.TUNNEL_PROTOCOL_OBFUSCATED_SSH:
  1059. inproxyOSSHPort = port
  1060. case protocol.TUNNEL_PROTOCOL_QUIC_OBFUSCATED_SSH:
  1061. inproxyQUICPort = port
  1062. case protocol.TUNNEL_PROTOCOL_UNFRONTED_MEEK_HTTPS,
  1063. protocol.TUNNEL_PROTOCOL_UNFRONTED_MEEK_SESSION_TICKET,
  1064. protocol.TUNNEL_PROTOCOL_UNFRONTED_MEEK:
  1065. inproxyMeekPort = port
  1066. case protocol.TUNNEL_PROTOCOL_SHADOWSOCKS_OSSH:
  1067. inproxyShadowsocksPort = port
  1068. }
  1069. }
  1070. }
  1071. // Note: fronting params are a stub; this server entry will exercise
  1072. // client and server fronting code paths, but not actually traverse
  1073. // a fronting hop.
  1074. serverEntry := &protocol.ServerEntry{
  1075. Tag: prng.Base64String(32),
  1076. IpAddress: params.ServerIPAddress,
  1077. WebServerSecret: webServerSecret,
  1078. TlsOSSHPort: tlsOSSHPort,
  1079. SshPort: sshPort,
  1080. SshUsername: sshUserName,
  1081. SshPassword: sshPassword,
  1082. SshHostKey: base64.RawStdEncoding.EncodeToString(sshPublicKey.Marshal()),
  1083. SshObfuscatedPort: obfuscatedSSHPort,
  1084. SshObfuscatedQUICPort: obfuscatedSSHQUICPort,
  1085. SshShadowsocksKey: shadowsocksKey,
  1086. SshShadowsocksPort: shadowsocksPort,
  1087. LimitQUICVersions: params.LimitQUICVersions,
  1088. SshObfuscatedKey: obfuscatedSSHKey,
  1089. Capabilities: capabilities,
  1090. Region: "US",
  1091. ProviderID: strings.ToUpper(prng.HexString(8)),
  1092. FrontingProviderID: frontingProviderID,
  1093. MeekServerPort: meekPort,
  1094. MeekCookieEncryptionPublicKey: meekCookieEncryptionPublicKey,
  1095. MeekObfuscatedKey: meekObfuscatedKey,
  1096. MeekFrontingHosts: []string{params.ServerIPAddress},
  1097. MeekFrontingAddresses: []string{params.ServerIPAddress},
  1098. MeekFrontingDisableSNI: false,
  1099. TacticsRequestPublicKey: tacticsRequestPublicKey,
  1100. TacticsRequestObfuscatedKey: tacticsRequestObfuscatedKey,
  1101. ConfigurationVersion: 1,
  1102. InproxySessionPublicKey: inproxyServerSessionPublicKey,
  1103. InproxySessionRootObfuscationSecret: inproxyServerObfuscationRootSecret,
  1104. InproxySSHPort: inproxySSHPort,
  1105. InproxyOSSHPort: inproxyOSSHPort,
  1106. InproxyQUICPort: inproxyQUICPort,
  1107. InproxyMeekPort: inproxyMeekPort,
  1108. InproxyTlsOSSHPort: inproxyTlsOSSHPort,
  1109. InproxyShadowsocksPort: inproxyShadowsocksPort,
  1110. }
  1111. if params.ServerEntrySignaturePublicKey != "" {
  1112. serverEntryJSON, err := json.Marshal(serverEntry)
  1113. if err != nil {
  1114. return nil, nil, nil, nil, nil, errors.Trace(err)
  1115. }
  1116. var serverEntryFields protocol.ServerEntryFields
  1117. err = json.Unmarshal(serverEntryJSON, &serverEntryFields)
  1118. if err != nil {
  1119. return nil, nil, nil, nil, nil, errors.Trace(err)
  1120. }
  1121. err = serverEntryFields.AddSignature(
  1122. params.ServerEntrySignaturePublicKey, params.ServerEntrySignaturePrivateKey)
  1123. if err != nil {
  1124. return nil, nil, nil, nil, nil, errors.Trace(err)
  1125. }
  1126. serverEntry, err = serverEntryFields.GetServerEntry()
  1127. if err != nil {
  1128. return nil, nil, nil, nil, nil, errors.Trace(err)
  1129. }
  1130. }
  1131. encodedServerEntry, err := protocol.EncodeServerEntry(serverEntry)
  1132. if err != nil {
  1133. return nil, nil, nil, nil, nil, errors.Trace(err)
  1134. }
  1135. return encodedConfig, encodedTrafficRulesSet, encodedOSLConfig, encodedTacticsConfig, []byte(encodedServerEntry), nil
  1136. }