ktls_test.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. package main
  2. import (
  3. "net/netip"
  4. "testing"
  5. "github.com/sagernet/sing-box/common/tls"
  6. C "github.com/sagernet/sing-box/constant"
  7. "github.com/sagernet/sing-box/option"
  8. "github.com/sagernet/sing/common"
  9. "github.com/sagernet/sing/common/json/badoption"
  10. "github.com/gofrs/uuid/v5"
  11. )
  12. func TestKTLS(t *testing.T) {
  13. _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
  14. startInstance(t, option.Options{
  15. Inbounds: []option.Inbound{
  16. {
  17. Type: C.TypeMixed,
  18. Tag: "mixed-in",
  19. Options: &option.HTTPMixedInboundOptions{
  20. ListenOptions: option.ListenOptions{
  21. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  22. ListenPort: clientPort,
  23. },
  24. },
  25. },
  26. {
  27. Type: C.TypeTrojan,
  28. Options: &option.TrojanInboundOptions{
  29. ListenOptions: option.ListenOptions{
  30. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  31. ListenPort: serverPort,
  32. },
  33. Users: []option.TrojanUser{
  34. {
  35. Name: "sekai",
  36. Password: "password",
  37. },
  38. },
  39. InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
  40. TLS: &option.InboundTLSOptions{
  41. Enabled: true,
  42. ServerName: "example.org",
  43. CertificatePath: certPem,
  44. KeyPath: keyPem,
  45. // KernelTx: true,
  46. },
  47. },
  48. },
  49. },
  50. },
  51. Outbounds: []option.Outbound{
  52. {
  53. Type: C.TypeDirect,
  54. },
  55. {
  56. Type: C.TypeTrojan,
  57. Tag: "trojan-out",
  58. Options: &option.TrojanOutboundOptions{
  59. ServerOptions: option.ServerOptions{
  60. Server: "127.0.0.1",
  61. ServerPort: serverPort,
  62. },
  63. Password: "password",
  64. OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
  65. TLS: &option.OutboundTLSOptions{
  66. Enabled: true,
  67. ServerName: "example.org",
  68. CertificatePath: certPem,
  69. KernelTx: true,
  70. KernelRx: true,
  71. },
  72. },
  73. },
  74. },
  75. },
  76. Route: &option.RouteOptions{
  77. Rules: []option.Rule{
  78. {
  79. Type: C.RuleTypeDefault,
  80. DefaultOptions: option.DefaultRule{
  81. RawDefaultRule: option.RawDefaultRule{
  82. Inbound: []string{"mixed-in"},
  83. },
  84. RuleAction: option.RuleAction{
  85. Action: C.RuleActionTypeRoute,
  86. RouteOptions: option.RouteActionOptions{
  87. Outbound: "trojan-out",
  88. },
  89. },
  90. },
  91. },
  92. },
  93. },
  94. })
  95. testSuit(t, clientPort, testPort)
  96. }
  97. func TestKTLSECH(t *testing.T) {
  98. _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
  99. echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org"))
  100. startInstance(t, option.Options{
  101. Inbounds: []option.Inbound{
  102. {
  103. Type: C.TypeMixed,
  104. Tag: "mixed-in",
  105. Options: &option.HTTPMixedInboundOptions{
  106. ListenOptions: option.ListenOptions{
  107. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  108. ListenPort: clientPort,
  109. },
  110. },
  111. },
  112. {
  113. Type: C.TypeTrojan,
  114. Options: &option.TrojanInboundOptions{
  115. ListenOptions: option.ListenOptions{
  116. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  117. ListenPort: serverPort,
  118. },
  119. Users: []option.TrojanUser{
  120. {
  121. Name: "sekai",
  122. Password: "password",
  123. },
  124. },
  125. InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
  126. TLS: &option.InboundTLSOptions{
  127. Enabled: true,
  128. ServerName: "example.org",
  129. CertificatePath: certPem,
  130. KeyPath: keyPem,
  131. KernelTx: true,
  132. ECH: &option.InboundECHOptions{
  133. Enabled: true,
  134. Key: []string{echKey},
  135. },
  136. },
  137. },
  138. },
  139. },
  140. },
  141. Outbounds: []option.Outbound{
  142. {
  143. Type: C.TypeDirect,
  144. },
  145. {
  146. Type: C.TypeTrojan,
  147. Tag: "trojan-out",
  148. Options: &option.TrojanOutboundOptions{
  149. ServerOptions: option.ServerOptions{
  150. Server: "127.0.0.1",
  151. ServerPort: serverPort,
  152. },
  153. Password: "password",
  154. OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
  155. TLS: &option.OutboundTLSOptions{
  156. Enabled: true,
  157. ServerName: "example.org",
  158. CertificatePath: certPem,
  159. KernelTx: true,
  160. KernelRx: true,
  161. ECH: &option.OutboundECHOptions{
  162. Enabled: true,
  163. Config: []string{echConfig},
  164. },
  165. },
  166. },
  167. },
  168. },
  169. },
  170. Route: &option.RouteOptions{
  171. Rules: []option.Rule{
  172. {
  173. Type: C.RuleTypeDefault,
  174. DefaultOptions: option.DefaultRule{
  175. RawDefaultRule: option.RawDefaultRule{
  176. Inbound: []string{"mixed-in"},
  177. },
  178. RuleAction: option.RuleAction{
  179. Action: C.RuleActionTypeRoute,
  180. RouteOptions: option.RouteActionOptions{
  181. Outbound: "trojan-out",
  182. },
  183. },
  184. },
  185. },
  186. },
  187. },
  188. })
  189. testSuit(t, clientPort, testPort)
  190. }
  191. func TestKTLSReality(t *testing.T) {
  192. user, _ := uuid.NewV4()
  193. startInstance(t, option.Options{
  194. Inbounds: []option.Inbound{
  195. {
  196. Type: C.TypeMixed,
  197. Tag: "mixed-in",
  198. Options: &option.HTTPMixedInboundOptions{
  199. ListenOptions: option.ListenOptions{
  200. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  201. ListenPort: clientPort,
  202. },
  203. },
  204. },
  205. {
  206. Type: C.TypeVLESS,
  207. Options: &option.VLESSInboundOptions{
  208. ListenOptions: option.ListenOptions{
  209. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  210. ListenPort: serverPort,
  211. },
  212. Users: []option.VLESSUser{{UUID: user.String()}},
  213. InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
  214. TLS: &option.InboundTLSOptions{
  215. Enabled: true,
  216. ServerName: "google.com",
  217. KernelTx: true,
  218. Reality: &option.InboundRealityOptions{
  219. Enabled: true,
  220. Handshake: option.InboundRealityHandshakeOptions{
  221. ServerOptions: option.ServerOptions{
  222. Server: "google.com",
  223. ServerPort: 443,
  224. },
  225. },
  226. ShortID: []string{"0123456789abcdef"},
  227. PrivateKey: "UuMBgl7MXTPx9inmQp2UC7Jcnwc6XYbwDNebonM-FCc",
  228. },
  229. },
  230. },
  231. },
  232. },
  233. },
  234. Outbounds: []option.Outbound{
  235. {
  236. Type: C.TypeDirect,
  237. },
  238. {
  239. Type: C.TypeVLESS,
  240. Tag: "ss-out",
  241. Options: &option.VLESSOutboundOptions{
  242. ServerOptions: option.ServerOptions{
  243. Server: "127.0.0.1",
  244. ServerPort: serverPort,
  245. },
  246. UUID: user.String(),
  247. OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
  248. TLS: &option.OutboundTLSOptions{
  249. Enabled: true,
  250. ServerName: "google.com",
  251. KernelTx: true,
  252. KernelRx: true,
  253. Reality: &option.OutboundRealityOptions{
  254. Enabled: true,
  255. ShortID: "0123456789abcdef",
  256. PublicKey: "jNXHt1yRo0vDuchQlIP6Z0ZvjT3KtzVI-T4E7RoLJS0",
  257. },
  258. UTLS: &option.OutboundUTLSOptions{
  259. Enabled: true,
  260. },
  261. },
  262. },
  263. },
  264. },
  265. },
  266. Route: &option.RouteOptions{
  267. Rules: []option.Rule{
  268. {
  269. Type: C.RuleTypeDefault,
  270. DefaultOptions: option.DefaultRule{
  271. RawDefaultRule: option.RawDefaultRule{
  272. Inbound: []string{"mixed-in"},
  273. },
  274. RuleAction: option.RuleAction{
  275. Action: C.RuleActionTypeRoute,
  276. RouteOptions: option.RouteActionOptions{
  277. Outbound: "ss-out",
  278. },
  279. },
  280. },
  281. },
  282. },
  283. },
  284. })
  285. testSuit(t, clientPort, testPort)
  286. }