ech_test.go 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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 TestECH(t *testing.T) {
  13. _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
  14. echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false))
  15. startInstance(t, option.Options{
  16. Inbounds: []option.Inbound{
  17. {
  18. Type: C.TypeMixed,
  19. Tag: "mixed-in",
  20. Options: &option.HTTPMixedInboundOptions{
  21. ListenOptions: option.ListenOptions{
  22. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  23. ListenPort: clientPort,
  24. },
  25. },
  26. },
  27. {
  28. Type: C.TypeTrojan,
  29. Options: &option.TrojanInboundOptions{
  30. ListenOptions: option.ListenOptions{
  31. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  32. ListenPort: serverPort,
  33. },
  34. Users: []option.TrojanUser{
  35. {
  36. Name: "sekai",
  37. Password: "password",
  38. },
  39. },
  40. InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
  41. TLS: &option.InboundTLSOptions{
  42. Enabled: true,
  43. ServerName: "example.org",
  44. CertificatePath: certPem,
  45. KeyPath: keyPem,
  46. ECH: &option.InboundECHOptions{
  47. Enabled: true,
  48. Key: []string{echKey},
  49. },
  50. },
  51. },
  52. },
  53. },
  54. },
  55. Outbounds: []option.Outbound{
  56. {
  57. Type: C.TypeDirect,
  58. },
  59. {
  60. Type: C.TypeTrojan,
  61. Tag: "trojan-out",
  62. Options: &option.TrojanOutboundOptions{
  63. ServerOptions: option.ServerOptions{
  64. Server: "127.0.0.1",
  65. ServerPort: serverPort,
  66. },
  67. Password: "password",
  68. OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
  69. TLS: &option.OutboundTLSOptions{
  70. Enabled: true,
  71. ServerName: "example.org",
  72. CertificatePath: certPem,
  73. ECH: &option.OutboundECHOptions{
  74. Enabled: true,
  75. Config: []string{echConfig},
  76. },
  77. },
  78. },
  79. },
  80. },
  81. },
  82. Route: &option.RouteOptions{
  83. Rules: []option.Rule{
  84. {
  85. Type: C.RuleTypeDefault,
  86. DefaultOptions: option.DefaultRule{
  87. RawDefaultRule: option.RawDefaultRule{
  88. Inbound: []string{"mixed-in"},
  89. },
  90. RuleAction: option.RuleAction{
  91. Action: C.RuleActionTypeRoute,
  92. RouteOptions: option.RouteActionOptions{
  93. Outbound: "trojan-out",
  94. },
  95. },
  96. },
  97. },
  98. },
  99. },
  100. })
  101. testSuit(t, clientPort, testPort)
  102. }
  103. func TestECHQUIC(t *testing.T) {
  104. _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
  105. echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false))
  106. startInstance(t, option.Options{
  107. Inbounds: []option.Inbound{
  108. {
  109. Type: C.TypeMixed,
  110. Tag: "mixed-in",
  111. Options: &option.HTTPMixedInboundOptions{
  112. ListenOptions: option.ListenOptions{
  113. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  114. ListenPort: clientPort,
  115. },
  116. },
  117. },
  118. {
  119. Type: C.TypeTUIC,
  120. Options: &option.TUICInboundOptions{
  121. ListenOptions: option.ListenOptions{
  122. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  123. ListenPort: serverPort,
  124. },
  125. Users: []option.TUICUser{{
  126. UUID: uuid.Nil.String(),
  127. }},
  128. InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
  129. TLS: &option.InboundTLSOptions{
  130. Enabled: true,
  131. ServerName: "example.org",
  132. CertificatePath: certPem,
  133. KeyPath: keyPem,
  134. ECH: &option.InboundECHOptions{
  135. Enabled: true,
  136. Key: []string{echKey},
  137. },
  138. },
  139. },
  140. },
  141. },
  142. },
  143. Outbounds: []option.Outbound{
  144. {
  145. Type: C.TypeDirect,
  146. },
  147. {
  148. Type: C.TypeTUIC,
  149. Tag: "tuic-out",
  150. Options: &option.TUICOutboundOptions{
  151. ServerOptions: option.ServerOptions{
  152. Server: "127.0.0.1",
  153. ServerPort: serverPort,
  154. },
  155. UUID: uuid.Nil.String(),
  156. OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
  157. TLS: &option.OutboundTLSOptions{
  158. Enabled: true,
  159. ServerName: "example.org",
  160. CertificatePath: certPem,
  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: "tuic-out",
  182. },
  183. },
  184. },
  185. },
  186. },
  187. },
  188. })
  189. testSuitLargeUDP(t, clientPort, testPort)
  190. }
  191. func TestECHHysteria2(t *testing.T) {
  192. _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
  193. echConfig, echKey := common.Must2(tls.ECHKeygenDefault("not.example.org", false))
  194. startInstance(t, option.Options{
  195. Inbounds: []option.Inbound{
  196. {
  197. Type: C.TypeMixed,
  198. Tag: "mixed-in",
  199. Options: &option.HTTPMixedInboundOptions{
  200. ListenOptions: option.ListenOptions{
  201. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  202. ListenPort: clientPort,
  203. },
  204. },
  205. },
  206. {
  207. Type: C.TypeHysteria2,
  208. Options: &option.Hysteria2InboundOptions{
  209. ListenOptions: option.ListenOptions{
  210. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  211. ListenPort: serverPort,
  212. },
  213. Users: []option.Hysteria2User{{
  214. Password: "password",
  215. }},
  216. InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
  217. TLS: &option.InboundTLSOptions{
  218. Enabled: true,
  219. ServerName: "example.org",
  220. CertificatePath: certPem,
  221. KeyPath: keyPem,
  222. ECH: &option.InboundECHOptions{
  223. Enabled: true,
  224. Key: []string{echKey},
  225. },
  226. },
  227. },
  228. },
  229. },
  230. },
  231. Outbounds: []option.Outbound{
  232. {
  233. Type: C.TypeDirect,
  234. },
  235. {
  236. Type: C.TypeHysteria2,
  237. Tag: "hy2-out",
  238. Options: &option.Hysteria2OutboundOptions{
  239. ServerOptions: option.ServerOptions{
  240. Server: "127.0.0.1",
  241. ServerPort: serverPort,
  242. },
  243. Password: "password",
  244. OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
  245. TLS: &option.OutboundTLSOptions{
  246. Enabled: true,
  247. ServerName: "example.org",
  248. CertificatePath: certPem,
  249. ECH: &option.OutboundECHOptions{
  250. Enabled: true,
  251. Config: []string{echConfig},
  252. },
  253. },
  254. },
  255. },
  256. },
  257. },
  258. Route: &option.RouteOptions{
  259. Rules: []option.Rule{
  260. {
  261. Type: C.RuleTypeDefault,
  262. DefaultOptions: option.DefaultRule{
  263. RawDefaultRule: option.RawDefaultRule{
  264. Inbound: []string{"mixed-in"},
  265. },
  266. RuleAction: option.RuleAction{
  267. Action: C.RuleActionTypeRoute,
  268. RouteOptions: option.RouteActionOptions{
  269. Outbound: "hy2-out",
  270. },
  271. },
  272. },
  273. },
  274. },
  275. },
  276. })
  277. testSuitLargeUDP(t, clientPort, testPort)
  278. }