@push.rocks/smartproxy 19.6.2 → 19.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist_ts/proxies/smart-proxy/connection-manager.d.ts +4 -7
  2. package/dist_ts/proxies/smart-proxy/connection-manager.js +22 -22
  3. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.d.ts +4 -3
  4. package/dist_ts/proxies/smart-proxy/http-proxy-bridge.js +9 -9
  5. package/dist_ts/proxies/smart-proxy/metrics-collector.d.ts +68 -56
  6. package/dist_ts/proxies/smart-proxy/metrics-collector.js +226 -176
  7. package/dist_ts/proxies/smart-proxy/models/interfaces.d.ts +5 -0
  8. package/dist_ts/proxies/smart-proxy/models/metrics-types.d.ts +94 -48
  9. package/dist_ts/proxies/smart-proxy/nftables-manager.d.ts +4 -4
  10. package/dist_ts/proxies/smart-proxy/nftables-manager.js +6 -6
  11. package/dist_ts/proxies/smart-proxy/port-manager.d.ts +4 -7
  12. package/dist_ts/proxies/smart-proxy/port-manager.js +6 -9
  13. package/dist_ts/proxies/smart-proxy/route-connection-handler.d.ts +4 -15
  14. package/dist_ts/proxies/smart-proxy/route-connection-handler.js +128 -128
  15. package/dist_ts/proxies/smart-proxy/security-manager.d.ts +3 -3
  16. package/dist_ts/proxies/smart-proxy/security-manager.js +9 -9
  17. package/dist_ts/proxies/smart-proxy/smart-proxy.d.ts +20 -13
  18. package/dist_ts/proxies/smart-proxy/smart-proxy.js +16 -13
  19. package/dist_ts/proxies/smart-proxy/throughput-tracker.d.ts +36 -0
  20. package/dist_ts/proxies/smart-proxy/throughput-tracker.js +117 -0
  21. package/dist_ts/proxies/smart-proxy/timeout-manager.d.ts +4 -3
  22. package/dist_ts/proxies/smart-proxy/timeout-manager.js +16 -16
  23. package/dist_ts/proxies/smart-proxy/tls-manager.d.ts +3 -3
  24. package/dist_ts/proxies/smart-proxy/tls-manager.js +12 -12
  25. package/package.json +8 -17
  26. package/readme.hints.md +0 -897
  27. package/readme.md +960 -54
  28. package/readme.plan.md +301 -562
  29. package/ts/proxies/smart-proxy/connection-manager.ts +23 -21
  30. package/ts/proxies/smart-proxy/http-proxy-bridge.ts +9 -8
  31. package/ts/proxies/smart-proxy/metrics-collector.ts +277 -189
  32. package/ts/proxies/smart-proxy/models/interfaces.ts +7 -0
  33. package/ts/proxies/smart-proxy/models/metrics-types.ts +93 -41
  34. package/ts/proxies/smart-proxy/nftables-manager.ts +5 -5
  35. package/ts/proxies/smart-proxy/port-manager.ts +6 -14
  36. package/ts/proxies/smart-proxy/route-connection-handler.ts +136 -136
  37. package/ts/proxies/smart-proxy/security-manager.ts +8 -8
  38. package/ts/proxies/smart-proxy/smart-proxy.ts +26 -35
  39. package/ts/proxies/smart-proxy/throughput-tracker.ts +144 -0
  40. package/ts/proxies/smart-proxy/timeout-manager.ts +16 -15
  41. package/ts/proxies/smart-proxy/tls-manager.ts +11 -11
  42. package/readme.connections.md +0 -724
  43. package/readme.delete.md +0 -187
  44. package/readme.memory-leaks-fixed.md +0 -45
  45. package/readme.metrics.md +0 -591
  46. package/readme.monitoring.md +0 -202
  47. package/readme.proxy-chain-summary.md +0 -112
  48. package/readme.proxy-protocol-example.md +0 -462
  49. package/readme.proxy-protocol.md +0 -415
  50. package/readme.routing.md +0 -341
  51. package/readme.websocket-keepalive-config.md +0 -140
  52. package/readme.websocket-keepalive-fix.md +0 -63
package/readme.md CHANGED
@@ -665,6 +665,661 @@ redirect: {
665
665
  }
666
666
  ```
667
667
 
668
+ ## Forwarding Modes Guide
669
+
670
+ This section provides a comprehensive reference for all forwarding modes available in SmartProxy, helping you choose the right configuration for your use case.
671
+
672
+ ### Visual Overview
673
+
674
+ ```mermaid
675
+ graph TD
676
+ A[Incoming Traffic] --> B{Action Type?}
677
+
678
+ B -->|forward| C{TLS Mode?}
679
+ B -->|socket-handler| D[Custom Handler]
680
+
681
+ C -->|terminate| E[Decrypt TLS]
682
+ C -->|passthrough| F[Forward Encrypted]
683
+ C -->|terminate-and-reencrypt| G[Decrypt & Re-encrypt]
684
+ C -->|none/HTTP| H[Forward HTTP]
685
+
686
+ E --> I{Engine?}
687
+ F --> I
688
+ G --> I
689
+ H --> I
690
+
691
+ I -->|node| J[Node.js Processing]
692
+ I -->|nftables| K[Kernel NAT]
693
+
694
+ J --> L[Backend]
695
+ K --> L
696
+ D --> M[Custom Logic]
697
+
698
+ style B fill:#f9f,stroke:#333,stroke-width:2px
699
+ style C fill:#bbf,stroke:#333,stroke-width:2px
700
+ style I fill:#bfb,stroke:#333,stroke-width:2px
701
+ ```
702
+
703
+ ### Overview
704
+
705
+ SmartProxy offers flexible traffic forwarding through combinations of:
706
+ - **Action Types**: How to handle matched traffic
707
+ - **TLS Modes**: How to handle HTTPS/TLS connections
708
+ - **Forwarding Engines**: Where packet processing occurs
709
+
710
+ ### Quick Reference
711
+
712
+ #### Modern Route-Based Configuration
713
+
714
+ | Use Case | Action Type | TLS Mode | Engine | Performance | Security |
715
+ |----------|------------|----------|---------|-------------|----------|
716
+ | HTTP web server | `forward` | N/A | `node` | Good | Basic |
717
+ | HTTPS web server (inspect traffic) | `forward` | `terminate` | `node` | Good | Full inspection |
718
+ | HTTPS passthrough (no inspection) | `forward` | `passthrough` | `node` | Better | End-to-end encryption |
719
+ | HTTPS gateway (re-encrypt to backend) | `forward` | `terminate-and-reencrypt` | `node` | Moderate | Full control |
720
+ | High-performance TCP forwarding | `forward` | `passthrough` | `nftables` | Excellent | Basic |
721
+ | Custom protocol handling | `socket-handler` | N/A | `node` | Varies | Custom |
722
+
723
+ #### Legacy Forwarding Types (Deprecated)
724
+
725
+ | Legacy Type | Modern Equivalent |
726
+ |------------|------------------|
727
+ | `http-only` | `action.type: 'forward'` with port 80 |
728
+ | `https-passthrough` | `action.type: 'forward'` + `tls.mode: 'passthrough'` |
729
+ | `https-terminate-to-http` | `action.type: 'forward'` + `tls.mode: 'terminate'` |
730
+ | `https-terminate-to-https` | `action.type: 'forward'` + `tls.mode: 'terminate-and-reencrypt'` |
731
+
732
+ ### Forwarding Mode Categories
733
+
734
+ #### 1. Action Types
735
+
736
+ ##### Forward Action
737
+ Routes traffic to a backend server. This is the most common action type.
738
+
739
+ ```typescript
740
+ {
741
+ action: {
742
+ type: 'forward',
743
+ target: {
744
+ host: 'backend-server',
745
+ port: 8080
746
+ }
747
+ }
748
+ }
749
+ ```
750
+
751
+ ##### Socket Handler Action
752
+ Provides custom handling for any TCP protocol. Used for specialized protocols or custom logic.
753
+
754
+ ```typescript
755
+ {
756
+ action: {
757
+ type: 'socket-handler',
758
+ socketHandler: async (socket, context) => {
759
+ // Custom protocol implementation
760
+ }
761
+ }
762
+ }
763
+ ```
764
+
765
+ #### 2. TLS Modes (for Forward Action)
766
+
767
+ ##### Passthrough Mode
768
+ - **What**: Forwards encrypted TLS traffic without decryption
769
+ - **When**: Backend handles its own TLS termination
770
+ - **Pros**: Maximum performance, true end-to-end encryption
771
+ - **Cons**: Cannot inspect or modify HTTPS traffic
772
+
773
+ ```mermaid
774
+ graph LR
775
+ Client -->|TLS| SmartProxy
776
+ SmartProxy -->|TLS| Backend
777
+ style SmartProxy fill:#f9f,stroke:#333,stroke-width:2px
778
+ ```
779
+
780
+ ##### Terminate Mode
781
+ - **What**: Decrypts TLS, forwards as plain HTTP
782
+ - **When**: Backend doesn't support HTTPS or you need to inspect traffic
783
+ - **Pros**: Can modify headers, inspect content, add security headers
784
+ - **Cons**: Backend connection is unencrypted
785
+
786
+ ```mermaid
787
+ graph LR
788
+ Client -->|TLS| SmartProxy
789
+ SmartProxy -->|HTTP| Backend
790
+ style SmartProxy fill:#f9f,stroke:#333,stroke-width:2px
791
+ ```
792
+
793
+ ##### Terminate-and-Reencrypt Mode
794
+ - **What**: Decrypts TLS, then creates new TLS connection to backend
795
+ - **When**: Need traffic inspection but backend requires HTTPS
796
+ - **Pros**: Full control while maintaining backend security
797
+ - **Cons**: Higher CPU usage, increased latency
798
+
799
+ ```mermaid
800
+ graph LR
801
+ Client -->|TLS| SmartProxy
802
+ SmartProxy -->|New TLS| Backend
803
+ style SmartProxy fill:#f9f,stroke:#333,stroke-width:2px
804
+ ```
805
+
806
+ #### 3. Forwarding Engines
807
+
808
+ ##### Node.js Engine (Default)
809
+ - **Processing**: Application-level in Node.js event loop
810
+ - **Features**: Full protocol support, header manipulation, WebSockets
811
+ - **Performance**: Good for most use cases
812
+ - **Use when**: You need application-layer features
813
+
814
+ ##### NFTables Engine
815
+ - **Processing**: Kernel-level packet forwarding
816
+ - **Features**: Basic NAT, minimal overhead
817
+ - **Performance**: Excellent, near wire-speed
818
+ - **Use when**: Maximum performance is critical
819
+ - **Requirements**: Linux, root permissions, NFTables installed
820
+
821
+ ### Detailed Mode Explanations
822
+
823
+ #### HTTP Forwarding (Port 80)
824
+
825
+ Simple HTTP forwarding without encryption:
826
+
827
+ ```typescript
828
+ {
829
+ match: { ports: 80, domains: 'example.com' },
830
+ action: {
831
+ type: 'forward',
832
+ target: { host: 'localhost', port: 8080 }
833
+ }
834
+ }
835
+ ```
836
+
837
+ **Data Flow**: Client → SmartProxy (HTTP) → Backend (HTTP)
838
+
839
+ #### HTTPS with TLS Termination
840
+
841
+ Decrypt HTTPS and forward as HTTP:
842
+
843
+ ```typescript
844
+ {
845
+ match: { ports: 443, domains: 'secure.example.com' },
846
+ action: {
847
+ type: 'forward',
848
+ target: { host: 'localhost', port: 8080 },
849
+ tls: {
850
+ mode: 'terminate',
851
+ certificate: 'auto' // Use Let's Encrypt
852
+ }
853
+ }
854
+ }
855
+ ```
856
+
857
+ **Data Flow**: Client → SmartProxy (HTTPS decrypt) → Backend (HTTP)
858
+
859
+ #### HTTPS Passthrough
860
+
861
+ Forward encrypted traffic without decryption:
862
+
863
+ ```typescript
864
+ {
865
+ match: { ports: 443, domains: 'legacy.example.com' },
866
+ action: {
867
+ type: 'forward',
868
+ target: { host: '192.168.1.10', port: 443 },
869
+ tls: {
870
+ mode: 'passthrough'
871
+ }
872
+ }
873
+ }
874
+ ```
875
+
876
+ **Data Flow**: Client → SmartProxy (TLS forwarding) → Backend (Original TLS)
877
+
878
+ #### HTTPS Gateway (Terminate and Re-encrypt)
879
+
880
+ Decrypt, inspect, then re-encrypt to backend:
881
+
882
+ ```typescript
883
+ {
884
+ match: { ports: 443, domains: 'api.example.com' },
885
+ action: {
886
+ type: 'forward',
887
+ target: { host: 'api-backend', port: 443 },
888
+ tls: {
889
+ mode: 'terminate-and-reencrypt',
890
+ certificate: 'auto'
891
+ },
892
+ advanced: {
893
+ headers: {
894
+ 'X-Forwarded-Proto': 'https',
895
+ 'X-Real-IP': '{clientIp}'
896
+ }
897
+ }
898
+ }
899
+ }
900
+ ```
901
+
902
+ **Data Flow**: Client → SmartProxy (HTTPS decrypt) → SmartProxy (New HTTPS) → Backend
903
+
904
+ #### High-Performance NFTables Forwarding
905
+
906
+ Kernel-level forwarding for maximum performance:
907
+
908
+ ```typescript
909
+ {
910
+ match: { ports: 443, domains: 'fast.example.com' },
911
+ action: {
912
+ type: 'forward',
913
+ target: { host: 'backend', port: 443 },
914
+ tls: { mode: 'passthrough' },
915
+ forwardingEngine: 'nftables',
916
+ nftables: {
917
+ preserveSourceIP: true,
918
+ maxRate: '10gbps'
919
+ }
920
+ }
921
+ }
922
+ ```
923
+
924
+ **Data Flow**: Client → Kernel (NFTables NAT) → Backend
925
+
926
+ #### Custom Socket Handler
927
+
928
+ Handle custom protocols or implement specialized logic:
929
+
930
+ ```typescript
931
+ {
932
+ match: { ports: 9000, domains: 'custom.example.com' },
933
+ action: {
934
+ type: 'socket-handler',
935
+ socketHandler: async (socket, context) => {
936
+ console.log(`Connection from ${context.clientIp}`);
937
+
938
+ socket.write('Welcome to custom protocol server\n');
939
+
940
+ socket.on('data', (data) => {
941
+ // Handle custom protocol
942
+ const response = processCustomProtocol(data);
943
+ socket.write(response);
944
+ });
945
+ }
946
+ }
947
+ }
948
+ ```
949
+
950
+ ### Decision Guide
951
+
952
+ #### Choose HTTP Forwarding When:
953
+ - Backend only supports HTTP
954
+ - Internal services not exposed to internet
955
+ - Development/testing environments
956
+
957
+ #### Choose HTTPS Termination When:
958
+ - Need to inspect/modify HTTP traffic
959
+ - Backend doesn't support HTTPS
960
+ - Want to add security headers
961
+ - Need to cache responses
962
+
963
+ #### Choose HTTPS Passthrough When:
964
+ - Backend manages its own certificates
965
+ - Need true end-to-end encryption
966
+ - Compliance requires no MITM
967
+ - WebSocket connections to backend
968
+
969
+ #### Choose HTTPS Terminate-and-Reencrypt When:
970
+ - Need traffic inspection AND backend requires HTTPS
971
+ - API gateway scenarios
972
+ - Adding authentication layers
973
+ - Different certificates for client/backend
974
+
975
+ #### Choose NFTables Engine When:
976
+ - Handling 1Gbps+ traffic
977
+ - Thousands of concurrent connections
978
+ - Minimal latency is critical
979
+ - Don't need application-layer features
980
+
981
+ #### Choose Socket Handler When:
982
+ - Implementing custom protocols
983
+ - Need fine-grained connection control
984
+ - Building protocol adapters
985
+ - Special authentication flows
986
+
987
+ ### Complete Examples
988
+
989
+ #### Example 1: Complete Web Application
990
+
991
+ ```typescript
992
+ const proxy = new SmartProxy({
993
+ routes: [
994
+ // HTTP to HTTPS redirect
995
+ {
996
+ match: { ports: 80, domains: ['example.com', 'www.example.com'] },
997
+ action: {
998
+ type: 'socket-handler',
999
+ socketHandler: SocketHandlers.httpRedirect('https://{domain}{path}')
1000
+ }
1001
+ },
1002
+
1003
+ // Main website with TLS termination
1004
+ {
1005
+ match: { ports: 443, domains: ['example.com', 'www.example.com'] },
1006
+ action: {
1007
+ type: 'forward',
1008
+ target: { host: 'web-backend', port: 3000 },
1009
+ tls: {
1010
+ mode: 'terminate',
1011
+ certificate: 'auto'
1012
+ },
1013
+ websocket: { enabled: true }
1014
+ }
1015
+ },
1016
+
1017
+ // API with re-encryption
1018
+ {
1019
+ match: { ports: 443, domains: 'api.example.com' },
1020
+ action: {
1021
+ type: 'forward',
1022
+ target: { host: 'api-backend', port: 443 },
1023
+ tls: {
1024
+ mode: 'terminate-and-reencrypt',
1025
+ certificate: 'auto'
1026
+ }
1027
+ },
1028
+ security: {
1029
+ ipAllowList: ['10.0.0.0/8'],
1030
+ rateLimit: {
1031
+ enabled: true,
1032
+ maxRequests: 100,
1033
+ window: 60
1034
+ }
1035
+ }
1036
+ }
1037
+ ]
1038
+ });
1039
+ ```
1040
+
1041
+ #### Example 2: Multi-Mode Proxy Setup
1042
+
1043
+ ```typescript
1044
+ const proxy = new SmartProxy({
1045
+ routes: [
1046
+ // Legacy app with passthrough
1047
+ {
1048
+ match: { ports: 443, domains: 'legacy.example.com' },
1049
+ action: {
1050
+ type: 'forward',
1051
+ target: { host: 'legacy-server', port: 443 },
1052
+ tls: { mode: 'passthrough' }
1053
+ }
1054
+ },
1055
+
1056
+ // High-performance streaming with NFTables
1057
+ {
1058
+ match: { ports: 8080, domains: 'stream.example.com' },
1059
+ action: {
1060
+ type: 'forward',
1061
+ target: { host: 'stream-backend', port: 8080 },
1062
+ forwardingEngine: 'nftables',
1063
+ nftables: {
1064
+ protocol: 'tcp',
1065
+ preserveSourceIP: true
1066
+ }
1067
+ }
1068
+ },
1069
+
1070
+ // Custom protocol handler
1071
+ {
1072
+ match: { ports: 9999 },
1073
+ action: {
1074
+ type: 'socket-handler',
1075
+ socketHandler: SocketHandlers.proxy('custom-backend', 9999)
1076
+ }
1077
+ }
1078
+ ]
1079
+ });
1080
+ ```
1081
+
1082
+ ### Performance Considerations
1083
+
1084
+ #### Node.js Engine Performance
1085
+
1086
+ | Metric | Typical Performance |
1087
+ |--------|-------------------|
1088
+ | Throughput | 1-10 Gbps |
1089
+ | Connections | 10,000-50,000 concurrent |
1090
+ | Latency | 1-5ms added |
1091
+ | CPU Usage | Moderate |
1092
+
1093
+ **Best for**: Most web applications, APIs, sites needing inspection
1094
+
1095
+ #### NFTables Engine Performance
1096
+
1097
+ | Metric | Typical Performance |
1098
+ |--------|-------------------|
1099
+ | Throughput | 10-100 Gbps |
1100
+ | Connections | 100,000+ concurrent |
1101
+ | Latency | <0.1ms added |
1102
+ | CPU Usage | Minimal |
1103
+
1104
+ **Best for**: High-traffic services, streaming, gaming, TCP forwarding
1105
+
1106
+ #### Performance Tips
1107
+
1108
+ 1. **Use passthrough mode** when you don't need inspection
1109
+ 2. **Enable NFTables** for high-traffic services
1110
+ 3. **Terminate TLS only when necessary** - it adds CPU overhead
1111
+ 4. **Use connection pooling** for terminate-and-reencrypt mode
1112
+ 5. **Enable HTTP/2** for better multiplexing
1113
+
1114
+ ### Security Implications
1115
+
1116
+ #### TLS Termination Security
1117
+
1118
+ **Pros:**
1119
+ - Inspect traffic for threats
1120
+ - Add security headers
1121
+ - Implement WAF rules
1122
+ - Log requests for audit
1123
+
1124
+ **Cons:**
1125
+ - Proxy has access to decrypted data
1126
+ - Requires secure certificate storage
1127
+ - Potential compliance issues
1128
+
1129
+ **Best Practices:**
1130
+ - Use auto-renewal with Let's Encrypt
1131
+ - Store certificates securely
1132
+ - Implement proper access controls
1133
+ - Use strong TLS configurations
1134
+
1135
+ #### Passthrough Security
1136
+
1137
+ **Pros:**
1138
+ - True end-to-end encryption
1139
+ - No MITM concerns
1140
+ - Backend controls security
1141
+
1142
+ **Cons:**
1143
+ - Cannot inspect traffic
1144
+ - Cannot add security headers
1145
+ - Limited DDoS protection
1146
+
1147
+ #### Socket Handler Security
1148
+
1149
+ **Risks:**
1150
+ - Custom code may have vulnerabilities
1151
+ - Resource exhaustion possible
1152
+ - Authentication bypass risks
1153
+
1154
+ **Mitigations:**
1155
+ ```typescript
1156
+ {
1157
+ action: {
1158
+ type: 'socket-handler',
1159
+ socketHandler: async (socket, context) => {
1160
+ // Always validate and sanitize input
1161
+ socket.on('data', (data) => {
1162
+ if (data.length > MAX_SIZE) {
1163
+ socket.destroy();
1164
+ return;
1165
+ }
1166
+ // Process safely...
1167
+ });
1168
+
1169
+ // Set timeouts
1170
+ socket.setTimeout(30000);
1171
+
1172
+ // Rate limit connections
1173
+ if (connectionsFromIP(context.clientIp) > 10) {
1174
+ socket.destroy();
1175
+ }
1176
+ }
1177
+ }
1178
+ }
1179
+ ```
1180
+
1181
+ ### Migration from Legacy Types
1182
+
1183
+ #### From `http-only`
1184
+
1185
+ **Old:**
1186
+ ```typescript
1187
+ {
1188
+ type: 'http-only',
1189
+ target: { host: 'localhost', port: 8080 }
1190
+ }
1191
+ ```
1192
+
1193
+ **New:**
1194
+ ```typescript
1195
+ {
1196
+ match: { ports: 80, domains: 'example.com' },
1197
+ action: {
1198
+ type: 'forward',
1199
+ target: { host: 'localhost', port: 8080 }
1200
+ }
1201
+ }
1202
+ ```
1203
+
1204
+ #### From `https-passthrough`
1205
+
1206
+ **Old:**
1207
+ ```typescript
1208
+ {
1209
+ type: 'https-passthrough',
1210
+ target: { host: 'backend', port: 443 }
1211
+ }
1212
+ ```
1213
+
1214
+ **New:**
1215
+ ```typescript
1216
+ {
1217
+ match: { ports: 443, domains: 'example.com' },
1218
+ action: {
1219
+ type: 'forward',
1220
+ target: { host: 'backend', port: 443 },
1221
+ tls: { mode: 'passthrough' }
1222
+ }
1223
+ }
1224
+ ```
1225
+
1226
+ #### From `https-terminate-to-http`
1227
+
1228
+ **Old:**
1229
+ ```typescript
1230
+ {
1231
+ type: 'https-terminate-to-http',
1232
+ target: { host: 'localhost', port: 8080 },
1233
+ ssl: { /* certs */ }
1234
+ }
1235
+ ```
1236
+
1237
+ **New:**
1238
+ ```typescript
1239
+ {
1240
+ match: { ports: 443, domains: 'example.com' },
1241
+ action: {
1242
+ type: 'forward',
1243
+ target: { host: 'localhost', port: 8080 },
1244
+ tls: {
1245
+ mode: 'terminate',
1246
+ certificate: 'auto' // or provide cert/key
1247
+ }
1248
+ }
1249
+ }
1250
+ ```
1251
+
1252
+ #### From `https-terminate-to-https`
1253
+
1254
+ **Old:**
1255
+ ```typescript
1256
+ {
1257
+ type: 'https-terminate-to-https',
1258
+ target: { host: 'backend', port: 443 },
1259
+ ssl: { /* certs */ }
1260
+ }
1261
+ ```
1262
+
1263
+ **New:**
1264
+ ```typescript
1265
+ {
1266
+ match: { ports: 443, domains: 'example.com' },
1267
+ action: {
1268
+ type: 'forward',
1269
+ target: { host: 'backend', port: 443 },
1270
+ tls: {
1271
+ mode: 'terminate-and-reencrypt',
1272
+ certificate: 'auto'
1273
+ }
1274
+ }
1275
+ }
1276
+ ```
1277
+
1278
+ ### Helper Functions Quick Reference
1279
+
1280
+ SmartProxy provides helper functions for common configurations:
1281
+
1282
+ ```typescript
1283
+ // HTTP forwarding
1284
+ createHttpRoute('example.com', { host: 'localhost', port: 8080 })
1285
+
1286
+ // HTTPS with termination
1287
+ createHttpsTerminateRoute('secure.com', { host: 'localhost', port: 8080 }, {
1288
+ certificate: 'auto'
1289
+ })
1290
+
1291
+ // HTTPS passthrough
1292
+ createHttpsPassthroughRoute('legacy.com', { host: 'backend', port: 443 })
1293
+
1294
+ // Complete HTTPS setup (includes HTTP redirect)
1295
+ ...createCompleteHttpsServer('example.com', { host: 'localhost', port: 8080 }, {
1296
+ certificate: 'auto'
1297
+ })
1298
+
1299
+ // NFTables high-performance
1300
+ createNfTablesRoute('fast.com', { host: 'backend', port: 8080 }, {
1301
+ ports: 80,
1302
+ preserveSourceIP: true
1303
+ })
1304
+
1305
+ // Custom socket handler
1306
+ createSocketHandlerRoute('custom.com', 9000, async (socket, context) => {
1307
+ // Handler implementation
1308
+ })
1309
+ ```
1310
+
1311
+ ### Summary
1312
+
1313
+ SmartProxy's forwarding modes provide flexibility for any proxy scenario:
1314
+
1315
+ - **Simple HTTP/HTTPS forwarding** for most web applications
1316
+ - **TLS passthrough** for end-to-end encryption
1317
+ - **TLS termination** for traffic inspection and modification
1318
+ - **NFTables** for extreme performance requirements
1319
+ - **Socket handlers** for custom protocols
1320
+
1321
+ Choose based on your security requirements, performance needs, and whether you need to inspect or modify traffic. The modern route-based configuration provides a consistent interface regardless of the forwarding mode you choose.
1322
+
668
1323
  ### Route Metadata and Prioritization
669
1324
 
670
1325
  You can add metadata to routes to help with organization and control matching priority:
@@ -921,122 +1576,316 @@ Available helper functions:
921
1576
 
922
1577
  ## Metrics and Monitoring
923
1578
 
924
- SmartProxy includes a comprehensive metrics collection system that provides real-time insights into proxy performance, connection statistics, and throughput data.
1579
+ SmartProxy includes a comprehensive metrics collection system that provides real-time insights into proxy performance, connection statistics, and throughput data. The metrics system uses a clean, grouped API design for intuitive access to different metric categories.
925
1580
 
926
- ### Getting Metrics
1581
+ ### Enabling Metrics
927
1582
 
928
1583
  ```typescript
929
- const proxy = new SmartProxy({ /* config */ });
1584
+ const proxy = new SmartProxy({
1585
+ // Enable metrics collection
1586
+ metrics: {
1587
+ enabled: true,
1588
+ sampleIntervalMs: 1000, // Sample throughput every second
1589
+ retentionSeconds: 3600 // Keep 1 hour of history
1590
+ },
1591
+ routes: [/* your routes */]
1592
+ });
1593
+
930
1594
  await proxy.start();
1595
+ ```
931
1596
 
932
- // Access metrics through the getStats() method
933
- const stats = proxy.getStats();
1597
+ ### Getting Metrics
934
1598
 
935
- // Get current active connections
936
- console.log(`Active connections: ${stats.getActiveConnections()}`);
1599
+ ```typescript
1600
+ // Access metrics through the getMetrics() method
1601
+ const metrics = proxy.getMetrics();
937
1602
 
938
- // Get total connections since start
939
- console.log(`Total connections: ${stats.getTotalConnections()}`);
1603
+ // The metrics object provides grouped methods for different categories
1604
+ ```
940
1605
 
941
- // Get requests per second (RPS)
942
- console.log(`Current RPS: ${stats.getRequestsPerSecond()}`);
1606
+ ### Connection Metrics
943
1607
 
944
- // Get throughput data
945
- const throughput = stats.getThroughput();
946
- console.log(`Bytes received: ${throughput.bytesIn}`);
947
- console.log(`Bytes sent: ${throughput.bytesOut}`);
1608
+ Monitor active connections, total connections, and connection distribution:
1609
+
1610
+ ```typescript
1611
+ // Get current active connections
1612
+ console.log(`Active connections: ${metrics.connections.active()}`);
1613
+
1614
+ // Get total connections since start
1615
+ console.log(`Total connections: ${metrics.connections.total()}`);
948
1616
 
949
1617
  // Get connections by route
950
- const routeConnections = stats.getConnectionsByRoute();
1618
+ const routeConnections = metrics.connections.byRoute();
951
1619
  for (const [route, count] of routeConnections) {
952
1620
  console.log(`Route ${route}: ${count} connections`);
953
1621
  }
954
1622
 
955
1623
  // Get connections by IP address
956
- const ipConnections = stats.getConnectionsByIP();
1624
+ const ipConnections = metrics.connections.byIP();
957
1625
  for (const [ip, count] of ipConnections) {
958
1626
  console.log(`IP ${ip}: ${count} connections`);
959
1627
  }
1628
+
1629
+ // Get top IPs by connection count
1630
+ const topIPs = metrics.connections.topIPs(10);
1631
+ topIPs.forEach(({ ip, count }) => {
1632
+ console.log(`${ip}: ${count} connections`);
1633
+ });
1634
+ ```
1635
+
1636
+ ### Throughput Metrics
1637
+
1638
+ Real-time and historical throughput data with customizable time windows:
1639
+
1640
+ ```typescript
1641
+ // Get instant throughput (last 1 second)
1642
+ const instant = metrics.throughput.instant();
1643
+ console.log(`Current: ${instant.in} bytes/sec in, ${instant.out} bytes/sec out`);
1644
+
1645
+ // Get recent throughput (last 10 seconds average)
1646
+ const recent = metrics.throughput.recent();
1647
+ console.log(`Recent: ${recent.in} bytes/sec in, ${recent.out} bytes/sec out`);
1648
+
1649
+ // Get average throughput (last 60 seconds)
1650
+ const average = metrics.throughput.average();
1651
+ console.log(`Average: ${average.in} bytes/sec in, ${average.out} bytes/sec out`);
1652
+
1653
+ // Get custom time window (e.g., last 5 minutes)
1654
+ const custom = metrics.throughput.custom(300);
1655
+ console.log(`5-min avg: ${custom.in} bytes/sec in, ${custom.out} bytes/sec out`);
1656
+
1657
+ // Get throughput history for graphing
1658
+ const history = metrics.throughput.history(300); // Last 5 minutes
1659
+ history.forEach(point => {
1660
+ console.log(`${new Date(point.timestamp)}: ${point.in} in, ${point.out} out`);
1661
+ });
1662
+
1663
+ // Get throughput by route
1664
+ const routeThroughput = metrics.throughput.byRoute(60); // Last 60 seconds
1665
+ routeThroughput.forEach((stats, route) => {
1666
+ console.log(`Route ${route}: ${stats.in} in, ${stats.out} out bytes/sec`);
1667
+ });
1668
+
1669
+ // Get throughput by IP
1670
+ const ipThroughput = metrics.throughput.byIP(60);
1671
+ ipThroughput.forEach((stats, ip) => {
1672
+ console.log(`IP ${ip}: ${stats.in} in, ${stats.out} out bytes/sec`);
1673
+ });
1674
+ ```
1675
+
1676
+ ### Request Metrics
1677
+
1678
+ Track request rates:
1679
+
1680
+ ```typescript
1681
+ // Get requests per second
1682
+ console.log(`RPS: ${metrics.requests.perSecond()}`);
1683
+
1684
+ // Get requests per minute
1685
+ console.log(`RPM: ${metrics.requests.perMinute()}`);
1686
+
1687
+ // Get total requests
1688
+ console.log(`Total requests: ${metrics.requests.total()}`);
1689
+ ```
1690
+
1691
+ ### Cumulative Totals
1692
+
1693
+ Track total bytes transferred and connections:
1694
+
1695
+ ```typescript
1696
+ // Get total bytes
1697
+ console.log(`Total bytes in: ${metrics.totals.bytesIn()}`);
1698
+ console.log(`Total bytes out: ${metrics.totals.bytesOut()}`);
1699
+ console.log(`Total connections: ${metrics.totals.connections()}`);
960
1700
  ```
961
1701
 
962
- ### Available Metrics
1702
+ ### Performance Percentiles
963
1703
 
964
- The `IProxyStats` interface provides the following methods:
1704
+ Get percentile statistics (when implemented):
965
1705
 
966
- - `getActiveConnections()`: Current number of active connections
967
- - `getTotalConnections()`: Total connections handled since proxy start
968
- - `getRequestsPerSecond()`: Current requests per second (1-minute average)
969
- - `getThroughput()`: Total bytes transferred (in/out)
970
- - `getConnectionsByRoute()`: Connection count per route
971
- - `getConnectionsByIP()`: Connection count per client IP
1706
+ ```typescript
1707
+ // Connection duration percentiles
1708
+ const durations = metrics.percentiles.connectionDuration();
1709
+ console.log(`Connection durations - P50: ${durations.p50}ms, P95: ${durations.p95}ms, P99: ${durations.p99}ms`);
1710
+
1711
+ // Bytes transferred percentiles
1712
+ const bytes = metrics.percentiles.bytesTransferred();
1713
+ console.log(`Bytes in - P50: ${bytes.in.p50}, P95: ${bytes.in.p95}, P99: ${bytes.in.p99}`);
1714
+ console.log(`Bytes out - P50: ${bytes.out.p50}, P95: ${bytes.out.p95}, P99: ${bytes.out.p99}`);
1715
+ ```
972
1716
 
973
- ### Monitoring Example
1717
+ ### Complete Monitoring Example
974
1718
 
975
1719
  ```typescript
976
- // Create a monitoring loop
1720
+ // Create a monitoring dashboard
977
1721
  setInterval(() => {
978
- const stats = proxy.getStats();
1722
+ const metrics = proxy.getMetrics();
979
1723
 
980
1724
  // Log key metrics
981
1725
  console.log({
982
1726
  timestamp: new Date().toISOString(),
983
- activeConnections: stats.getActiveConnections(),
984
- rps: stats.getRequestsPerSecond(),
985
- throughput: stats.getThroughput()
1727
+ connections: {
1728
+ active: metrics.connections.active(),
1729
+ total: metrics.connections.total()
1730
+ },
1731
+ throughput: {
1732
+ instant: metrics.throughput.instant(),
1733
+ average: metrics.throughput.average()
1734
+ },
1735
+ requests: {
1736
+ rps: metrics.requests.perSecond(),
1737
+ total: metrics.requests.total()
1738
+ },
1739
+ totals: {
1740
+ bytesIn: metrics.totals.bytesIn(),
1741
+ bytesOut: metrics.totals.bytesOut()
1742
+ }
986
1743
  });
987
1744
 
988
- // Check for high connection counts from specific IPs
989
- const ipConnections = stats.getConnectionsByIP();
990
- for (const [ip, count] of ipConnections) {
1745
+ // Alert on high connection counts
1746
+ const topIPs = metrics.connections.topIPs(5);
1747
+ topIPs.forEach(({ ip, count }) => {
991
1748
  if (count > 100) {
992
1749
  console.warn(`High connection count from ${ip}: ${count}`);
993
1750
  }
1751
+ });
1752
+
1753
+ // Alert on high throughput
1754
+ const instant = metrics.throughput.instant();
1755
+ if (instant.in > 100_000_000) { // 100 MB/s
1756
+ console.warn(`High incoming throughput: ${instant.in} bytes/sec`);
994
1757
  }
995
1758
  }, 10000); // Every 10 seconds
996
1759
  ```
997
1760
 
998
1761
  ### Exporting Metrics
999
1762
 
1000
- You can export metrics in various formats for external monitoring systems:
1763
+ Export metrics in various formats for external monitoring systems:
1001
1764
 
1002
1765
  ```typescript
1003
1766
  // Export as JSON
1004
1767
  app.get('/metrics.json', (req, res) => {
1005
- const stats = proxy.getStats();
1768
+ const metrics = proxy.getMetrics();
1006
1769
  res.json({
1007
- activeConnections: stats.getActiveConnections(),
1008
- totalConnections: stats.getTotalConnections(),
1009
- requestsPerSecond: stats.getRequestsPerSecond(),
1010
- throughput: stats.getThroughput(),
1011
- connectionsByRoute: Object.fromEntries(stats.getConnectionsByRoute()),
1012
- connectionsByIP: Object.fromEntries(stats.getConnectionsByIP())
1770
+ connections: {
1771
+ active: metrics.connections.active(),
1772
+ total: metrics.connections.total(),
1773
+ byRoute: Object.fromEntries(metrics.connections.byRoute()),
1774
+ byIP: Object.fromEntries(metrics.connections.byIP())
1775
+ },
1776
+ throughput: {
1777
+ instant: metrics.throughput.instant(),
1778
+ recent: metrics.throughput.recent(),
1779
+ average: metrics.throughput.average()
1780
+ },
1781
+ requests: {
1782
+ perSecond: metrics.requests.perSecond(),
1783
+ perMinute: metrics.requests.perMinute(),
1784
+ total: metrics.requests.total()
1785
+ },
1786
+ totals: {
1787
+ bytesIn: metrics.totals.bytesIn(),
1788
+ bytesOut: metrics.totals.bytesOut(),
1789
+ connections: metrics.totals.connections()
1790
+ }
1013
1791
  });
1014
1792
  });
1015
1793
 
1016
1794
  // Export as Prometheus format
1017
1795
  app.get('/metrics', (req, res) => {
1018
- const stats = proxy.getStats();
1796
+ const metrics = proxy.getMetrics();
1797
+ const instant = metrics.throughput.instant();
1798
+
1019
1799
  res.set('Content-Type', 'text/plain');
1020
1800
  res.send(`
1021
- # HELP smartproxy_active_connections Current active connections
1022
- # TYPE smartproxy_active_connections gauge
1023
- smartproxy_active_connections ${stats.getActiveConnections()}
1801
+ # HELP smartproxy_connections_active Current active connections
1802
+ # TYPE smartproxy_connections_active gauge
1803
+ smartproxy_connections_active ${metrics.connections.active()}
1804
+
1805
+ # HELP smartproxy_connections_total Total connections since start
1806
+ # TYPE smartproxy_connections_total counter
1807
+ smartproxy_connections_total ${metrics.connections.total()}
1808
+
1809
+ # HELP smartproxy_throughput_bytes_per_second Current throughput in bytes per second
1810
+ # TYPE smartproxy_throughput_bytes_per_second gauge
1811
+ smartproxy_throughput_bytes_per_second{direction="in"} ${instant.in}
1812
+ smartproxy_throughput_bytes_per_second{direction="out"} ${instant.out}
1024
1813
 
1025
1814
  # HELP smartproxy_requests_per_second Current requests per second
1026
1815
  # TYPE smartproxy_requests_per_second gauge
1027
- smartproxy_requests_per_second ${stats.getRequestsPerSecond()}
1816
+ smartproxy_requests_per_second ${metrics.requests.perSecond()}
1028
1817
 
1029
- # HELP smartproxy_bytes_in Total bytes received
1030
- # TYPE smartproxy_bytes_in counter
1031
- smartproxy_bytes_in ${stats.getThroughput().bytesIn}
1032
-
1033
- # HELP smartproxy_bytes_out Total bytes sent
1034
- # TYPE smartproxy_bytes_out counter
1035
- smartproxy_bytes_out ${stats.getThroughput().bytesOut}
1818
+ # HELP smartproxy_bytes_total Total bytes transferred
1819
+ # TYPE smartproxy_bytes_total counter
1820
+ smartproxy_bytes_total{direction="in"} ${metrics.totals.bytesIn()}
1821
+ smartproxy_bytes_total{direction="out"} ${metrics.totals.bytesOut()}
1036
1822
  `);
1037
1823
  });
1038
1824
  ```
1039
1825
 
1826
+ ### Metrics API Reference
1827
+
1828
+ The metrics API is organized into logical groups:
1829
+
1830
+ ```typescript
1831
+ interface IMetrics {
1832
+ connections: {
1833
+ active(): number;
1834
+ total(): number;
1835
+ byRoute(): Map<string, number>;
1836
+ byIP(): Map<string, number>;
1837
+ topIPs(limit?: number): Array<{ ip: string; count: number }>;
1838
+ };
1839
+
1840
+ throughput: {
1841
+ instant(): IThroughputData; // Last 1 second
1842
+ recent(): IThroughputData; // Last 10 seconds
1843
+ average(): IThroughputData; // Last 60 seconds
1844
+ custom(seconds: number): IThroughputData;
1845
+ history(seconds: number): Array<IThroughputHistoryPoint>;
1846
+ byRoute(windowSeconds?: number): Map<string, IThroughputData>;
1847
+ byIP(windowSeconds?: number): Map<string, IThroughputData>;
1848
+ };
1849
+
1850
+ requests: {
1851
+ perSecond(): number;
1852
+ perMinute(): number;
1853
+ total(): number;
1854
+ };
1855
+
1856
+ totals: {
1857
+ bytesIn(): number;
1858
+ bytesOut(): number;
1859
+ connections(): number;
1860
+ };
1861
+
1862
+ percentiles: {
1863
+ connectionDuration(): { p50: number; p95: number; p99: number };
1864
+ bytesTransferred(): {
1865
+ in: { p50: number; p95: number; p99: number };
1866
+ out: { p50: number; p95: number; p99: number };
1867
+ };
1868
+ };
1869
+ }
1870
+ ```
1871
+
1872
+ Where `IThroughputData` is:
1873
+ ```typescript
1874
+ interface IThroughputData {
1875
+ in: number; // Bytes per second incoming
1876
+ out: number; // Bytes per second outgoing
1877
+ }
1878
+ ```
1879
+
1880
+ And `IThroughputHistoryPoint` is:
1881
+ ```typescript
1882
+ interface IThroughputHistoryPoint {
1883
+ timestamp: number; // Unix timestamp in milliseconds
1884
+ in: number; // Bytes per second at this point
1885
+ out: number; // Bytes per second at this point
1886
+ }
1887
+ ```
1888
+
1040
1889
  ## Other Components
1041
1890
 
1042
1891
  While SmartProxy provides a unified API for most needs, you can also use individual components:
@@ -1736,6 +2585,62 @@ createHttpToHttpsRedirect('old.example.com', 443)
1736
2585
  }
1737
2586
  ```
1738
2587
 
2588
+ ## WebSocket Keep-Alive Configuration
2589
+
2590
+ If your WebSocket connections are disconnecting every 30 seconds in SNI passthrough mode, here's how to configure keep-alive settings:
2591
+
2592
+ ### Extended Keep-Alive Treatment (Recommended)
2593
+
2594
+ ```typescript
2595
+ const proxy = new SmartProxy({
2596
+ // Extend timeout for keep-alive connections
2597
+ keepAliveTreatment: 'extended',
2598
+ keepAliveInactivityMultiplier: 10, // 10x the base timeout
2599
+ inactivityTimeout: 14400000, // 4 hours base (40 hours with multiplier)
2600
+
2601
+ routes: [
2602
+ {
2603
+ name: 'websocket-passthrough',
2604
+ match: {
2605
+ ports: 443,
2606
+ domains: ['ws.example.com', 'wss.example.com']
2607
+ },
2608
+ action: {
2609
+ type: 'forward',
2610
+ target: { host: 'backend', port: 443 },
2611
+ tls: { mode: 'passthrough' }
2612
+ }
2613
+ }
2614
+ ]
2615
+ });
2616
+ ```
2617
+
2618
+ ### Immortal Connections (Never Timeout)
2619
+
2620
+ ```typescript
2621
+ const proxy = new SmartProxy({
2622
+ // Never timeout keep-alive connections
2623
+ keepAliveTreatment: 'immortal',
2624
+
2625
+ routes: [
2626
+ // ... same as above
2627
+ ]
2628
+ });
2629
+ ```
2630
+
2631
+ ### Understanding the Issue
2632
+
2633
+ In SNI passthrough mode:
2634
+ 1. **WebSocket Heartbeat**: The HTTP proxy's WebSocket handler sends ping frames every 30 seconds
2635
+ 2. **SNI Passthrough**: In passthrough mode, traffic is encrypted end-to-end
2636
+ 3. **Can't Inject Pings**: The proxy can't inject ping frames into encrypted traffic
2637
+ 4. **Connection Terminated**: After 30 seconds, connection is marked inactive and closed
2638
+
2639
+ The solution involves:
2640
+ - Longer grace periods for encrypted connections (5 minutes vs 30 seconds)
2641
+ - Relying on OS-level TCP keep-alive instead of application-level heartbeat
2642
+ - Different timeout strategies per route type
2643
+
1739
2644
  ## Configuration Options
1740
2645
 
1741
2646
  ### SmartProxy (IRoutedSmartProxyOptions)
@@ -1746,6 +2651,7 @@ createHttpToHttpsRedirect('old.example.com', 443)
1746
2651
  - `httpProxyPort` (number, default 8443) - Port where HttpProxy listens for forwarded connections
1747
2652
  - Connection timeouts: `initialDataTimeout`, `socketTimeout`, `inactivityTimeout`, etc.
1748
2653
  - Socket opts: `noDelay`, `keepAlive`, `enableKeepAliveProbes`
2654
+ - Keep-alive configuration: `keepAliveTreatment` ('standard'|'extended'|'immortal'), `keepAliveInactivityMultiplier`
1749
2655
  - `certProvisionFunction` (callback) - Custom certificate provisioning
1750
2656
 
1751
2657
  #### SmartProxy Dynamic Port Management Methods