├── README.md ├── config.json └── genconf.php /README.md: -------------------------------------------------------------------------------- 1 | tunlr-style-dns-unblocking 2 | ========================== 3 | 4 | **Attention: the proxy list is outdated and as of May 2015, many services don't work anymore (including the demo proxy server). Since the underlying ideas are still valid, I'm leaving the project here as a reference but won't update it anymore.** 5 | 6 | **Click here for an easier to install and more recent alternative: https://github.com/trick77/dockerflix** 7 | 8 | Since Tunlr.net closed down unexpectedly, I decided to publish my ideas and findings on the subject of DNS unblocking. I used Tunlr for some time when I decided to develop my own, private DNS unblocking solution. I'm using a combination of Dnsmasq and HAProxy. Because IPv4 addresses are getting more and more expensive, I'm focusing on solutions that require just a single public IP address. You will have to compile HAProxy on your own if you don't get a version >= 1.5 using yum/apt-get. Alternatively, you can get a recent HAProxy binary from a (untrusted) repository: http://haproxy.debian.net. Make sure the JSON-Library is available for PHP. 9 | 10 | THIS IS NOT A TUTORIAL! 11 | 12 | The configuration generator (genconf.php) offers three different modes: 13 | - pure-sni (Simple Setup) 14 | - non-sni (Advanced Setup) 15 | - local (Advanced Setup) 16 | 17 | See here for additional information: 18 | 19 | - http://trick77.com/2014/03/01/tunlr-style-dns-unblocking-pandora-netflix-hulu-et-al/ 20 | - http://trick77.com/2014/03/02/dns-unblocking-using-dnsmasq-haproxy/ 21 | 22 | I'm currently running a HAProxy-based DNS-unblocker on 199.204.184.146 so you can start with your DNS forwarder setup first and add your own HAProxy server later. This server supports the pure-sni mode only. 23 | Here's a tester which may help while deploying your own DNS unblocking solution: 24 | 25 | http://trick77.com/dns-unblocking-setup-tester/ 26 | 27 | Want to add a service to config.json or found an outdated configuration section? Please send a pull request with the updated configuration. 28 | 29 | #### pure-sni (Simple Setup) 30 | 31 | Use this setup if all your multimedia players are SNI-capable. 32 | 33 | Requires a U.S. based server (a 128 MB low end VPS is enough) and preferrably a local Dnsmasq DNS forwarder. DD-WRT routers or a Raspberry Pi will do. You could run Dnsmasq on the remote server as well but it's not recommended for security and latency reasons. 34 | 35 | In pure-sni mode, you don't have to worry about the dnat_base_ip, dnat_base_port and loopback_base_ip options. Those options are not used, just leave them at their defaults. Make sure iptables_location points to the iptables executable and enter your VPS' IP address in haproxy_bind_ip. Make sure the ports 80 and 443 on your VPS are not being used by some other software like Apache2. Use ```netstat -tulpn``` to make sure. 36 | 37 | For this mode, call the generator like this: 38 | ```php genconf.php pure-sni``` 39 | 40 | The generator will create two files based on the information in json.config: 41 | - haproxy.conf 42 | - dnsmasq-haproxy.conf 43 | 44 | Test your new setup with http://trick77.com/dns-unblocking-setup-tester/ 45 | 46 | #### non-sni (Advanced Setup) 47 | 48 | non-sni mode enables DNS-unblocking for multimedia players (or applications) which can't handle SNI but still using just a single IP address using some netfilter trickery. See here for more information on this mode: 49 | http://trick77.com/2014/04/02/netflix-dns-unblocking-without-sni-xbox-360-ps3-samsung-tv/ 50 | 51 | Test your new setup with http://trick77.com/dns-unblocking-setup-tester/ 52 | 53 | Non-conclusive list of devices which don't understand SNI: 54 | - Xbox 360 55 | - PS3 56 | - All Sony Bravia TVs and Blu-ray players 57 | - Older Samsung TVs 58 | 59 | #### local (Advanced Setup) 60 | 61 | local mode enables DNS-unblocking on a single device which can't handle SNI but still using just a single IP address and without using another server on the network. 62 | The generator will create four files based on the information in json.config: 63 | - haproxy.conf (for the remote server) 64 | - netsh-haproxy.cmd (for Windows) 65 | - rinetd-haproxy.conf (for Linux) 66 | - hosts-haproxy.txt (for Linux/Windows) 67 | 68 | For Windows: 69 | - Run notepad as administrator and open %SystemRoot%\system32\drivers\etc\hosts (usually c:\windows\system32\drivers\etc\hosts), copy the contents of hosts-haproxy.txt 70 | - Run netsh-haproxy.cmd as administrator 71 | 72 | - To reset: delete contents of %SystemRoot%\system32\drivers\etc\hosts, run as administrator 'netsh interface portproxy reset' 73 | 74 | For Linux: 75 | - Run 'sudo tee -a /etc/hosts < hosts-haproxy.txt' (or append hots-haproxy.txt to /etc/hosts) 76 | - Run 'sudo cp rinetd-haproxy.conf /etc/rinetd.conf && sudo service rinetd start' 77 | 78 | - To reset: 'sudo sed -i '/### GENERATED/d' /etc/hosts' and 'sudo service rinetd stop && sudo rm /etc/rinetd.conf' 79 | 80 | #### Too complicated? 81 | 82 | Check out https://github.com/skorokithakis/netproxy for a ready-made DNS-unblocking solution using Docker! 83 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "iptables_location": "/sbin/iptables", // Required to generate iptables rules 3 | "haproxy_bind_ip": "199.204.184.146", // IP address of your remote server, required for every mode 4 | "dnat_base_ip": "192.168.178.51", // Only required for mode "non-sni" 5 | "dnat_base_port": 27200, // Only required for mode "non-sni" 6 | "loopback_base_ip": "127.0.0.51", // Only required for mode "local" 7 | "server_options": "check inter 60s fastinter 10s downinter 10s fall 1800", // Don't touch unless you know what you're doing 8 | "stats": { 9 | "enabled": true, // Set to true to enable HAProxy stats web page 10 | "port": 27199, 11 | "user": "haproxy", 12 | "password": "Change-Me-Now" 13 | }, 14 | // *** PROXY CONFIGURATION STARTS HERE 15 | "proxies":[ 16 | { 17 | "name":"humble-bundle", 18 | "dest_addr":"www.humblebundle.com", 19 | "modes":[ 20 | { 21 | "port":80, 22 | "mode":"http" 23 | }, 24 | { 25 | "port":443, 26 | "mode":"https" 27 | } 28 | ], 29 | "catchall":false, 30 | "enabled":true 31 | }, 32 | { 33 | "name":"hulu-secure", 34 | "dest_addr":"s.hulu.com", 35 | "modes":[ 36 | { 37 | "port":80, 38 | "mode":"http" 39 | }, 40 | { 41 | "port":443, 42 | "mode":"https" 43 | } 44 | ], 45 | "catchall":false, 46 | "enabled":true 47 | }, 48 | { 49 | "name":"hulu-play", 50 | "dest_addr":"play.hulu.com", 51 | "modes":[ 52 | { 53 | "port":80, 54 | "mode":"http" 55 | }, 56 | { 57 | "port":443, 58 | "mode":"https" 59 | } 60 | ], 61 | "catchall":false, 62 | "enabled":true 63 | }, 64 | { 65 | "name":"netflix-signup", 66 | "dest_addr":"signup.netflix.com", 67 | "modes":[ 68 | { 69 | "port":80, 70 | "mode":"http" 71 | }, 72 | { 73 | "port":443, 74 | "mode":"https" 75 | } 76 | ], 77 | "catchall":false, 78 | "enabled":true 79 | }, 80 | { 81 | "name":"netflix-www", 82 | "dest_addr":"www.netflix.com", 83 | "modes":[ 84 | { 85 | "port":80, 86 | "mode":"http" 87 | }, 88 | { 89 | "port":443, 90 | "mode":"https" 91 | } 92 | ], 93 | "catchall":false, 94 | "enabled":true 95 | }, 96 | { 97 | "name":"netflix-appboot", 98 | "dest_addr":"appboot.netflix.com", 99 | "modes":[ 100 | { 101 | "port":80, 102 | "mode":"http" 103 | }, 104 | { 105 | "port":443, 106 | "mode":"https" 107 | } 108 | ], 109 | "catchall":false, 110 | "enabled":true 111 | }, 112 | { 113 | "name":"netflix-cbp-us", 114 | "dest_addr":"cbp-us.nccp.netflix.com", 115 | "modes":[ 116 | { 117 | "port":80, 118 | "mode":"http" 119 | }, 120 | { 121 | "port":443, 122 | "mode":"https" 123 | } 124 | ], 125 | "catchall":false, 126 | "enabled":true 127 | }, 128 | { 129 | "name":"netflix-akamai", 130 | "dest_addr":"a248.e.akamai.net", 131 | "modes":[ 132 | { 133 | "port":80, 134 | "mode":"http" 135 | }, 136 | { 137 | "port":443, 138 | "mode":"https" 139 | } 140 | ], 141 | "catchall":false, 142 | "enabled":true 143 | }, 144 | { 145 | "name":"netflix-api-global", 146 | "dest_addr":"api-global.netflix.com", 147 | "modes":[ 148 | { 149 | "port":80, 150 | "mode":"http" 151 | }, 152 | { 153 | "port":443, 154 | "mode":"https" 155 | } 156 | ], 157 | "catchall":false, 158 | "enabled":true 159 | }, 160 | { 161 | "name":"netflix-movies", 162 | "dest_addr":"movies.netflix.com", 163 | "modes":[ 164 | { 165 | "port":80, 166 | "mode":"http" 167 | }, 168 | { 169 | "port":443, 170 | "mode":"https" 171 | } 172 | ], 173 | "catchall":false, 174 | "enabled":true 175 | }, 176 | { 177 | "name":"netflix-movies1", 178 | "dest_addr":"movies1.netflix.com", 179 | "modes":[ 180 | { 181 | "port":80, 182 | "mode":"http" 183 | }, 184 | { 185 | "port":443, 186 | "mode":"https" 187 | } 188 | ], 189 | "catchall":false, 190 | "enabled":true 191 | }, 192 | { 193 | "name":"netflix-secure", 194 | "dest_addr":"secure.netflix.com", 195 | "modes":[ 196 | { 197 | "port":80, 198 | "mode":"http" 199 | }, 200 | { 201 | "port":443, 202 | "mode":"https" 203 | } 204 | ], 205 | "catchall":false, 206 | "enabled":true 207 | }, 208 | { 209 | "name":"netflix-moviecontrol", 210 | "dest_addr":"moviecontrol.netflix.com", 211 | "modes":[ 212 | { 213 | "port":80, 214 | "mode":"http" 215 | }, 216 | { 217 | "port":443, 218 | "mode":"https" 219 | } 220 | ], 221 | "catchall":false, 222 | "enabled":true 223 | }, 224 | { 225 | "name":"netflix-api", 226 | "dest_addr":"api.netflix.com", 227 | "modes":[ 228 | { 229 | "port":80, 230 | "mode":"http" 231 | }, 232 | { 233 | "port":443, 234 | "mode":"https" 235 | } 236 | ], 237 | "catchall":false, 238 | "enabled":true 239 | }, 240 | { 241 | "name":"netflix-api-us", 242 | "dest_addr":"api-us.netflix.com", 243 | "modes":[ 244 | { 245 | "port":80, 246 | "mode":"http" 247 | }, 248 | { 249 | "port":443, 250 | "mode":"https" 251 | } 252 | ], 253 | "catchall":false, 254 | "enabled":true 255 | }, 256 | { 257 | "name":"netflix-uiboot", 258 | "dest_addr":"uiboot.netflix.com", 259 | "modes":[ 260 | { 261 | "port":80, 262 | "mode":"http" 263 | }, 264 | { 265 | "port":443, 266 | "mode":"https" 267 | } 268 | ], 269 | "catchall":false, 270 | "enabled":true 271 | }, 272 | { 273 | "name":"netflix-cbp", 274 | "dest_addr":"cbp.nccp.netflix.com", 275 | "modes":[ 276 | { 277 | "port":80, 278 | "mode":"http" 279 | }, 280 | { 281 | "port":443, 282 | "mode":"https" 283 | } 284 | ], 285 | "catchall":false, 286 | "enabled":true 287 | }, 288 | { 289 | "name":"netflix-ios", 290 | "dest_addr":"ios.nccp.netflix.com", 291 | "modes":[ 292 | { 293 | "port":80, 294 | "mode":"http" 295 | }, 296 | { 297 | "port":443, 298 | "mode":"https" 299 | } 300 | ], 301 | "catchall":true, 302 | "enabled":true 303 | }, 304 | { 305 | "name":"netflix-xbox", 306 | "dest_addr":"xbox.nccp.netflix.com", 307 | "modes":[ 308 | { 309 | "port":80, 310 | "mode":"http" 311 | }, 312 | { 313 | "port":443, 314 | "mode":"https" 315 | } 316 | ], 317 | "catchall":false, 318 | "enabled":true 319 | }, 320 | { 321 | "name":"netflix-nrdp-31", 322 | "dest_addr":"nccp-nrdp-31.cloud.netflix.net", 323 | "modes":[ 324 | { 325 | "port":80, 326 | "mode":"http" 327 | }, 328 | { 329 | "port":443, 330 | "mode":"https" 331 | } 332 | ], 333 | "catchall":false, 334 | "enabled":true 335 | }, 336 | { 337 | "name":"netflix-nintendo", 338 | "dest_addr":"nintendo.nccp.netflix.com", 339 | "modes":[ 340 | { 341 | "port":80, 342 | "mode":"http" 343 | }, 344 | { 345 | "port":443, 346 | "mode":"https" 347 | } 348 | ], 349 | "catchall":false, 350 | "enabled":true 351 | }, 352 | { 353 | "name":"netflix-playstation", 354 | "dest_addr":"playstation.nccp.netflix.com", 355 | "modes":[ 356 | { 357 | "port":80, 358 | "mode":"http" 359 | }, 360 | { 361 | "port":443, 362 | "mode":"https" 363 | } 364 | ], 365 | "catchall":false, 366 | "enabled":true 367 | }, 368 | { 369 | "name":"netflix-nrdp", 370 | "dest_addr":"nrdp.nccp.netflix.com", 371 | "modes":[ 372 | { 373 | "port":80, 374 | "mode":"http" 375 | }, 376 | { 377 | "port":443, 378 | "mode":"https" 379 | } 380 | ], 381 | "catchall":false, 382 | "enabled":true 383 | }, 384 | { 385 | "name":"netflix-android", 386 | "dest_addr":"android.nccp.netflix.com", 387 | "modes":[ 388 | { 389 | "port":80, 390 | "mode":"http" 391 | }, 392 | { 393 | "port":443, 394 | "mode":"https" 395 | } 396 | ], 397 | "catchall":true, 398 | "enabled":true 399 | }, 400 | { 401 | "name":"netflix-playstation-net", 402 | "dest_addr":"video.dl.playstation.net", 403 | "modes":[ 404 | { 405 | "port":80, 406 | "mode":"http" 407 | }, 408 | { 409 | "port":443, 410 | "mode":"https" 411 | } 412 | ], 413 | "catchall":false, 414 | "enabled":true 415 | }, 416 | { 417 | "name":"netflix-ssm", 418 | "dest_addr":"ssm.internet.sony.tv", 419 | "modes":[ 420 | { 421 | "port":80, 422 | "mode":"http" 423 | }, 424 | { 425 | "port":443, 426 | "mode":"https" 427 | } 428 | ], 429 | "catchall":false, 430 | "enabled":true 431 | }, 432 | { 433 | "name":"netflix-ssm1", 434 | "dest_addr":"ssm1.internet.sony.tv", 435 | "modes":[ 436 | { 437 | "port":80, 438 | "mode":"http" 439 | }, 440 | { 441 | "port":443, 442 | "mode":"https" 443 | } 444 | ], 445 | "catchall":false, 446 | "enabled":true 447 | }, 448 | { 449 | "name":"netflix-ssm2", 450 | "dest_addr":"ssm2.internet.sony.tv", 451 | "modes":[ 452 | { 453 | "port":80, 454 | "mode":"http" 455 | }, 456 | { 457 | "port":443, 458 | "mode":"https" 459 | } 460 | ], 461 | "catchall":false, 462 | "enabled":true 463 | }, 464 | { 465 | "name":"netflix-ssm3", 466 | "dest_addr":"ssm3.internet.sony.tv", 467 | "modes":[ 468 | { 469 | "port":80, 470 | "mode":"http" 471 | }, 472 | { 473 | "port":443, 474 | "mode":"https" 475 | } 476 | ], 477 | "catchall":false, 478 | "enabled":true 479 | }, 480 | { 481 | "name":"netflix-treb", 482 | "dest_addr":"treb.internet.sony.tv", 483 | "modes":[ 484 | { 485 | "port":80, 486 | "mode":"http" 487 | }, 488 | { 489 | "port":443, 490 | "mode":"https" 491 | } 492 | ], 493 | "catchall":false, 494 | "enabled":true 495 | }, 496 | { 497 | "name":"netflix-wdtv", 498 | "dest_addr":"www.wdtvlive.com", 499 | "modes":[ 500 | { 501 | "port":80, 502 | "mode":"http" 503 | } 504 | ], 505 | "catchall":false, 506 | "enabled":true 507 | }, 508 | { 509 | "name":"pandora-www", 510 | "dest_addr":"www.pandora.com", 511 | "modes":[ 512 | { 513 | "port":80, 514 | "mode":"http" 515 | }, 516 | { 517 | "port":443, 518 | "mode":"https" 519 | } 520 | ], 521 | "catchall":true, 522 | "enabled":true 523 | }, 524 | { 525 | "name":"pandora-tuner", 526 | "dest_addr":"tuner.pandora.com", 527 | "modes":[ 528 | { 529 | "port":80, 530 | "mode":"http" 531 | }, 532 | { 533 | "port":443, 534 | "mode":"https" 535 | } 536 | ], 537 | "catchall":false, 538 | "enabled":true 539 | }, 540 | { 541 | "name":"pandora-mediaserver", 542 | "dest_addr":"mediaserver-sv5-rt-1.pandora.com", 543 | "modes":[ 544 | { 545 | "port":80, 546 | "mode":"http" 547 | } 548 | ], 549 | "catchall":true, 550 | "enabled":true 551 | }, 552 | { 553 | "name":"abc-go", 554 | "dest_addr":"abc.go.com", 555 | "modes":[ 556 | { 557 | "port":80, 558 | "mode":"http" 559 | }, 560 | { 561 | "port":443, 562 | "mode":"https" 563 | } 564 | ], 565 | "catchall":true, 566 | "enabled":true 567 | }, 568 | { 569 | "name":"abc-disney", 570 | "dest_addr":"api.watchdisneyxd.go.com", 571 | "modes":[ 572 | { 573 | "port":80, 574 | "mode":"http" 575 | }, 576 | { 577 | "port":443, 578 | "mode":"https" 579 | } 580 | ], 581 | "catchall":true, 582 | "enabled":true 583 | }, 584 | { 585 | "name":"abc—utils-watchabc", 586 | "dest_addr":"api.utils.watchabc.go.com", 587 | "modes":[ 588 | { 589 | "port":80, 590 | "mode":"http" 591 | }, 592 | { 593 | "port":443, 594 | "mode":"https" 595 | } 596 | ], 597 | "catchall":true, 598 | "enabled":true 599 | }, 600 | { 601 | "name":"abc—legacypresentation-watchabc", 602 | "dest_addr":"api.legacypresentation.watchabc.go.com", 603 | "modes":[ 604 | { 605 | "port":80, 606 | "mode":"http" 607 | }, 608 | { 609 | "port":443, 610 | "mode":"https" 611 | } 612 | ], 613 | "catchall":true, 614 | "enabled":true 615 | }, 616 | { 617 | "name":"crackle-www", 618 | "dest_addr":"www.crackle.com", 619 | "modes":[ 620 | { 621 | "port":80, 622 | "mode":"http" 623 | }, 624 | { 625 | "port":443, 626 | "mode":"https" 627 | } 628 | ], 629 | "catchall":true, 630 | "enabled":true 631 | }, 632 | { 633 | "name":"crackle-api", 634 | "dest_addr":"api.crackle.com", 635 | "modes":[ 636 | { 637 | "port":80, 638 | "mode":"http" 639 | }, 640 | { 641 | "port":443, 642 | "mode":"https" 643 | } 644 | ], 645 | "catchall":true, 646 | "enabled":true 647 | }, 648 | { 649 | "name":"crackle-ios", 650 | "dest_addr":"ios-api.crackle.com", 651 | "modes":[ 652 | { 653 | "port":80, 654 | "mode":"http" 655 | }, 656 | { 657 | "port":443, 658 | "mode":"https" 659 | } 660 | ], 661 | "catchall":true, 662 | "enabled":true 663 | }, 664 | { 665 | "name":"crackle-ios-us", 666 | "dest_addr":"ios-api-us.crackle.com", 667 | "modes":[ 668 | { 669 | "port":80, 670 | "mode":"http" 671 | }, 672 | { 673 | "port":443, 674 | "mode":"https" 675 | } 676 | ], 677 | "catchall":true, 678 | "enabled":true 679 | }, 680 | { 681 | "name":"crackle-appletv", 682 | "dest_addr":"appletv.crackle.com", 683 | "modes":[ 684 | { 685 | "port":80, 686 | "mode":"http" 687 | }, 688 | { 689 | "port":443, 690 | "mode":"https" 691 | } 692 | ], 693 | "catchall":true, 694 | "enabled":true 695 | }, 696 | { 697 | "name":"crackle-android", 698 | "dest_addr":"android-api-us.crackle.com", 699 | "modes":[ 700 | { 701 | "port":80, 702 | "mode":"http" 703 | }, 704 | { 705 | "port":443, 706 | "mode":"https" 707 | } 708 | ], 709 | "catchall":true, 710 | "enabled":true 711 | }, 712 | { 713 | "name":"crackle-xboxone", 714 | "dest_addr":"xboxone-api-us.crackle.com", 715 | "modes":[ 716 | { 717 | "port":80, 718 | "mode":"http" 719 | }, 720 | { 721 | "port":443, 722 | "mode":"https" 723 | } 724 | ], 725 | "catchall":false, 726 | "enabled":true 727 | }, 728 | { 729 | "name":"crackle-ps3", 730 | "dest_addr":"ps3-api-us.crackle.com", 731 | "modes":[ 732 | { 733 | "port":80, 734 | "mode":"http" 735 | }, 736 | { 737 | "port":443, 738 | "mode":"https" 739 | } 740 | ], 741 | "catchall":false, 742 | "enabled":true 743 | }, 744 | { 745 | "name":"crackle-roku", 746 | "dest_addr":"roku-api.crackle.com", 747 | "modes":[ 748 | { 749 | "port":80, 750 | "mode":"http" 751 | }, 752 | { 753 | "port":443, 754 | "mode":"https" 755 | } 756 | ], 757 | "catchall":false, 758 | "enabled":true 759 | }, 760 | { 761 | "name":"crackle-uplynk", 762 | "dest_addr":"content.uplynk.com", 763 | "modes":[ 764 | { 765 | "port":80, 766 | "mode":"http" 767 | }, 768 | { 769 | "port":443, 770 | "mode":"https" 771 | } 772 | ], 773 | "catchall":false, 774 | "enabled":true 775 | }, 776 | { 777 | "name":"mylifetime", 778 | "dest_addr":"c.brightcove.com", 779 | "modes":[ 780 | { 781 | "port":80, 782 | "mode":"http" 783 | } 784 | ], 785 | "catchall":true, 786 | "enabled":true 787 | }, 788 | { 789 | "name":"cbs", 790 | "dest_addr":"release.theplatform.com", 791 | "modes":[ 792 | { 793 | "port":80, 794 | "mode":"http" 795 | }, 796 | { 797 | "port":443, 798 | "mode":"https" 799 | } 800 | ], 801 | "catchall":true, 802 | "enabled":true 803 | }, 804 | { 805 | "name":"crunchyroll-www", 806 | "dest_addr":"www.crunchyroll.com", 807 | "modes":[ 808 | { 809 | "port":80, 810 | "mode":"http" 811 | }, 812 | { 813 | "port":443, 814 | "mode":"https" 815 | } 816 | ], 817 | "catchall":true, 818 | "enabled":true 819 | }, 820 | { 821 | "name":"crunchyroll-api", 822 | "dest_addr":"api.crunchyroll.com", 823 | "modes":[ 824 | { 825 | "port":80, 826 | "mode":"http" 827 | }, 828 | { 829 | "port":443, 830 | "mode":"https" 831 | } 832 | ], 833 | "catchall":true, 834 | "enabled":true 835 | }, 836 | { 837 | "name":"dramafever-www", 838 | "dest_addr":"www.dramafever.com", 839 | "modes":[ 840 | { 841 | "port":80, 842 | "mode":"http" 843 | }, 844 | { 845 | "port":443, 846 | "mode":"https" 847 | } 848 | ], 849 | "catchall":true, 850 | "enabled":true 851 | }, 852 | { 853 | "name":"dramafever-token", 854 | "dest_addr":"token.dramafever.com", 855 | "modes":[ 856 | { 857 | "port":80, 858 | "mode":"http" 859 | }, 860 | { 861 | "port":443, 862 | "mode":"https" 863 | } 864 | ], 865 | "catchall":true, 866 | "enabled":true 867 | }, 868 | { 869 | "name":"discovery", 870 | "dest_addr":"static.discoverymedia.com", 871 | "modes":[ 872 | { 873 | "port":80, 874 | "mode":"http" 875 | }, 876 | { 877 | "port":443, 878 | "mode":"https" 879 | } 880 | ], 881 | "catchall":true, 882 | "enabled":true 883 | }, 884 | { 885 | "name":"fox", 886 | "dest_addr":"link.theplatform.com", 887 | "modes":[ 888 | { 889 | "port":80, 890 | "mode":"http" 891 | }, 892 | { 893 | "port":443, 894 | "mode":"https" 895 | } 896 | ], 897 | "catchall":true, 898 | "enabled":true 899 | }, 900 | { 901 | "name":"iheart", 902 | "dest_addr":"www.iheart.com", 903 | "modes":[ 904 | { 905 | "port":80, 906 | "mode":"http" 907 | }, 908 | { 909 | "port":443, 910 | "mode":"https" 911 | } 912 | ], 913 | "catchall":true, 914 | "enabled":true 915 | }, 916 | { 917 | "name":"lastfm-www", 918 | "dest_addr":"www.last.fm", 919 | "modes":[ 920 | { 921 | "port":80, 922 | "mode":"http" 923 | }, 924 | { 925 | "port":443, 926 | "mode":"https" 927 | } 928 | ], 929 | "catchall":true, 930 | "enabled":true 931 | }, 932 | { 933 | "name":"lastfm-audioscrobbler", 934 | "dest_addr":"ws.audioscrobbler.com", 935 | "modes":[ 936 | { 937 | "port":80, 938 | "mode":"http" 939 | }, 940 | { 941 | "port":443, 942 | "mode":"https" 943 | } 944 | ], 945 | "catchall":true, 946 | "enabled":true 947 | }, 948 | { 949 | "name":"lastfm-ext", 950 | "dest_addr":"ext.last.fm", 951 | "modes":[ 952 | { 953 | "port":80, 954 | "mode":"http" 955 | }, 956 | { 957 | "port":443, 958 | "mode":"https" 959 | } 960 | ], 961 | "catchall":true, 962 | "enabled":true 963 | }, 964 | { 965 | "name":"logotv-www", 966 | "dest_addr":"www.logotv.com", 967 | "modes":[ 968 | { 969 | "port":80, 970 | "mode":"http" 971 | }, 972 | { 973 | "port":443, 974 | "mode":"https" 975 | } 976 | ], 977 | "catchall":true, 978 | "enabled":true 979 | }, 980 | { 981 | "name":"logotv-flux", 982 | "dest_addr":"activity.flux.com", 983 | "modes":[ 984 | { 985 | "port":80, 986 | "mode":"http" 987 | }, 988 | { 989 | "port":443, 990 | "mode":"https" 991 | } 992 | ], 993 | "catchall":true, 994 | "enabled":true 995 | }, 996 | { 997 | "name":"maxmind", 998 | "dest_addr":"j.maxmind.com", 999 | "modes":[ 1000 | { 1001 | "port":80, 1002 | "mode":"http" 1003 | }, 1004 | { 1005 | "port":443, 1006 | "mode":"https" 1007 | } 1008 | ], 1009 | "catchall":true, 1010 | "enabled":true 1011 | }, 1012 | { 1013 | "name":"mog", 1014 | "dest_addr":"mog.com", 1015 | "modes":[ 1016 | { 1017 | "port":80, 1018 | "mode":"http" 1019 | }, 1020 | { 1021 | "port":443, 1022 | "mode":"https" 1023 | } 1024 | ], 1025 | "catchall":true, 1026 | "enabled":true 1027 | }, 1028 | { 1029 | "name":"mtv-www", 1030 | "dest_addr":"www.mtv.com", 1031 | "modes":[ 1032 | { 1033 | "port":80, 1034 | "mode":"http" 1035 | }, 1036 | { 1037 | "port":443, 1038 | "mode":"https" 1039 | } 1040 | ], 1041 | "catchall":true, 1042 | "enabled":true 1043 | }, 1044 | { 1045 | "name":"mtv-udat", 1046 | "dest_addr":"udat.mtvnservices.com", 1047 | "modes":[ 1048 | { 1049 | "port":80, 1050 | "mode":"http" 1051 | }, 1052 | { 1053 | "port":443, 1054 | "mode":"https" 1055 | } 1056 | ], 1057 | "catchall":true, 1058 | "enabled":true 1059 | }, 1060 | { 1061 | "name":"mtv-media", 1062 | "dest_addr":"media.mtvnservices.com", 1063 | "modes":[ 1064 | { 1065 | "port":80, 1066 | "mode":"http" 1067 | }, 1068 | { 1069 | "port":443, 1070 | "mode":"https" 1071 | } 1072 | ], 1073 | "catchall":true, 1074 | "enabled":true 1075 | }, 1076 | { 1077 | "name":"nbc-uni", 1078 | "dest_addr":"video.nbcuni.com", 1079 | "modes":[ 1080 | { 1081 | "port":80, 1082 | "mode":"http" 1083 | }, 1084 | { 1085 | "port":443, 1086 | "mode":"https" 1087 | } 1088 | ], 1089 | "catchall":true, 1090 | "enabled":true 1091 | }, 1092 | { 1093 | "name":"nbc-nbc", 1094 | "dest_addr":"video.nbc.com", 1095 | "modes":[ 1096 | { 1097 | "port":80, 1098 | "mode":"http" 1099 | }, 1100 | { 1101 | "port":443, 1102 | "mode":"https" 1103 | } 1104 | ], 1105 | "catchall":true, 1106 | "enabled":true 1107 | }, 1108 | { 1109 | "name":"nbc-syfy", 1110 | "dest_addr":"video.syfy.com", 1111 | "modes":[ 1112 | { 1113 | "port":80, 1114 | "mode":"http" 1115 | }, 1116 | { 1117 | "port":443, 1118 | "mode":"https" 1119 | } 1120 | ], 1121 | "catchall":true, 1122 | "enabled":true 1123 | }, 1124 | { 1125 | "name":"pbs", 1126 | "dest_addr":"urs.pbs.org", 1127 | "modes":[ 1128 | { 1129 | "port":80, 1130 | "mode":"http" 1131 | } 1132 | ], 1133 | "catchall":false, 1134 | "enabled":true 1135 | }, 1136 | { 1137 | "name":"smithsonian-www", 1138 | "dest_addr":"www.smithsonianchannel.com", 1139 | "modes":[ 1140 | { 1141 | "port":80, 1142 | "mode":"http" 1143 | }, 1144 | { 1145 | "port":443, 1146 | "mode":"https" 1147 | } 1148 | ], 1149 | "catchall":true, 1150 | "enabled":true 1151 | }, 1152 | { 1153 | "name":"smithsonian-unicorn", 1154 | "dest_addr":"once.unicornmedia.com", 1155 | "modes":[ 1156 | { 1157 | "port":80, 1158 | "mode":"http" 1159 | }, 1160 | { 1161 | "port":443, 1162 | "mode":"https" 1163 | } 1164 | ], 1165 | "catchall":true, 1166 | "enabled":true 1167 | }, 1168 | { 1169 | "name":"spike-www", 1170 | "dest_addr":"www.spike.com", 1171 | "modes":[ 1172 | { 1173 | "port":80, 1174 | "mode":"http" 1175 | }, 1176 | { 1177 | "port":443, 1178 | "mode":"https" 1179 | } 1180 | ], 1181 | "catchall":true, 1182 | "enabled":true 1183 | }, 1184 | { 1185 | "name":"thewb-www", 1186 | "dest_addr":"www.thewb.com", 1187 | "modes":[ 1188 | { 1189 | "port":80, 1190 | "mode":"http" 1191 | } 1192 | ], 1193 | "catchall":true, 1194 | "enabled":true 1195 | }, 1196 | { 1197 | "name":"thewb-cwtv", 1198 | "dest_addr":"www.cwtv.com", 1199 | "modes":[ 1200 | { 1201 | "port":80, 1202 | "mode":"http" 1203 | }, 1204 | { 1205 | "port":443, 1206 | "mode":"https" 1207 | } 1208 | ], 1209 | "catchall":true, 1210 | "enabled":true 1211 | }, 1212 | { 1213 | "name":"thewb-cwtv-media", 1214 | "dest_addr":"media.cwtv.com", 1215 | "modes":[ 1216 | { 1217 | "port":80, 1218 | "mode":"http" 1219 | } 1220 | ], 1221 | "catchall":true, 1222 | "enabled":true 1223 | }, 1224 | { 1225 | "name":"thewb-pdl", 1226 | "dest_addr":"pdl.warnerbros.com", 1227 | "modes":[ 1228 | { 1229 | "port":80, 1230 | "mode":"http" 1231 | } 1232 | ], 1233 | "catchall":true, 1234 | "enabled":true 1235 | }, 1236 | { 1237 | "name":"thewb-cdn", 1238 | "dest_addr":"cdn.wwtv.warnerbros.com", 1239 | "modes":[ 1240 | { 1241 | "port":80, 1242 | "mode":"http" 1243 | } 1244 | ], 1245 | "catchall":true, 1246 | "enabled":true 1247 | }, 1248 | { 1249 | "name":"vevo-www", 1250 | "dest_addr":"www.vevo.com", 1251 | "modes":[ 1252 | { 1253 | "port":80, 1254 | "mode":"http" 1255 | }, 1256 | { 1257 | "port":443, 1258 | "mode":"https" 1259 | } 1260 | ], 1261 | "catchall":true, 1262 | "enabled":true 1263 | }, 1264 | { 1265 | "name":"vevo-sb", 1266 | "dest_addr":"sb.vevo.com", 1267 | "modes":[ 1268 | { 1269 | "port":80, 1270 | "mode":"http" 1271 | }, 1272 | { 1273 | "port":443, 1274 | "mode":"https" 1275 | } 1276 | ], 1277 | "catchall":true, 1278 | "enabled":true 1279 | }, 1280 | { 1281 | "name":"vevo-videoplayer", 1282 | "dest_addr":"videoplayer.vevo.com", 1283 | "modes":[ 1284 | { 1285 | "port":80, 1286 | "mode":"http" 1287 | }, 1288 | { 1289 | "port":443, 1290 | "mode":"https" 1291 | } 1292 | ], 1293 | "catchall":true, 1294 | "enabled":true 1295 | }, 1296 | { 1297 | "name":"vh1", 1298 | "dest_addr":"www.vh1.com", 1299 | "modes":[ 1300 | { 1301 | "port":80, 1302 | "mode":"http" 1303 | }, 1304 | { 1305 | "port":443, 1306 | "mode":"https" 1307 | } 1308 | ], 1309 | "catchall":true, 1310 | "enabled":true 1311 | }, 1312 | { 1313 | "name":"yahoo-screen", 1314 | "dest_addr":"screen.yahoo.com", 1315 | "modes":[ 1316 | { 1317 | "port":80, 1318 | "mode":"http" 1319 | }, 1320 | { 1321 | "port":443, 1322 | "mode":"https" 1323 | } 1324 | ], 1325 | "catchall":true, 1326 | "enabled":true 1327 | }, 1328 | { 1329 | "name":"yahoo-geo", 1330 | "dest_addr":"geo.yahoo.com", 1331 | "modes":[ 1332 | { 1333 | "port":80, 1334 | "mode":"http" 1335 | }, 1336 | { 1337 | "port":443, 1338 | "mode":"https" 1339 | } 1340 | ], 1341 | "catchall":true, 1342 | "enabled":true 1343 | }, 1344 | { 1345 | "name":"yahoo-geo-query", 1346 | "dest_addr":"geo.query.yahoo.com", 1347 | "modes":[ 1348 | { 1349 | "port":80, 1350 | "mode":"http" 1351 | }, 1352 | { 1353 | "port":443, 1354 | "mode":"https" 1355 | } 1356 | ], 1357 | "catchall":true, 1358 | "enabled":true 1359 | }, 1360 | { 1361 | "name":"yahoo-mvid", 1362 | "dest_addr":"mvid.yql.yahoo.com", 1363 | "modes":[ 1364 | { 1365 | "port":80, 1366 | "mode":"http" 1367 | }, 1368 | { 1369 | "port":443, 1370 | "mode":"https" 1371 | } 1372 | ], 1373 | "catchall":true, 1374 | "enabled":true 1375 | }, 1376 | { 1377 | "name":"yahoo-hls", 1378 | "dest_addr":"hls.video.query.yahoo.com", 1379 | "modes":[ 1380 | { 1381 | "port":80, 1382 | "mode":"http" 1383 | }, 1384 | { 1385 | "port":443, 1386 | "mode":"https" 1387 | } 1388 | ], 1389 | "catchall":true, 1390 | "enabled":true 1391 | }, 1392 | { 1393 | "name":"usopen-geo", 1394 | "dest_addr":"usgageo.edgesuite.net", 1395 | "modes":[ 1396 | { 1397 | "port":80, 1398 | "mode":"http" 1399 | }, 1400 | { 1401 | "port":443, 1402 | "mode":"https" 1403 | } 1404 | ], 1405 | "catchall":true, 1406 | "enabled":true 1407 | }, 1408 | { 1409 | "name":"nbc-akamai-ipad", 1410 | "dest_addr":"tve_nbc-vh.akamaihd.net", 1411 | "modes":[ 1412 | { 1413 | "port":80, 1414 | "mode":"http" 1415 | }, 1416 | { 1417 | "port":443, 1418 | "mode":"https" 1419 | } 1420 | ], 1421 | "catchall":true, 1422 | "enabled":true 1423 | }, 1424 | { 1425 | "name":"cbs-akamai-ipad", 1426 | "dest_addr":"ipad-streaming.cbs.com", 1427 | "modes":[ 1428 | { 1429 | "port":80, 1430 | "mode":"http" 1431 | }, 1432 | { 1433 | "port":443, 1434 | "mode":"https" 1435 | } 1436 | ], 1437 | "catchall":true, 1438 | "enabled":true 1439 | }, 1440 | { 1441 | "name":"www-sony-net", 1442 | "dest_addr":"www.sony.net", 1443 | "modes":[ 1444 | { 1445 | "port":80, 1446 | "mode":"http" 1447 | }, 1448 | { 1449 | "port":443, 1450 | "mode":"https" 1451 | } 1452 | ], 1453 | "catchall":false, 1454 | "enabled":true 1455 | }, 1456 | { 1457 | "name":"internet-sony-tv", 1458 | "dest_addr":"internet.sony.tv", 1459 | "modes":[ 1460 | { 1461 | "port":80, 1462 | "mode":"http" 1463 | }, 1464 | { 1465 | "port":443, 1466 | "mode":"https" 1467 | } 1468 | ], 1469 | "catchall":false, 1470 | "enabled":true 1471 | }, 1472 | { 1473 | "name":"applicast-ga-sony-net", 1474 | "dest_addr":"applicast.ga.sony.net", 1475 | "modes":[ 1476 | { 1477 | "port":80, 1478 | "mode":"http" 1479 | }, 1480 | { 1481 | "port":443, 1482 | "mode":"https" 1483 | } 1484 | ], 1485 | "catchall":false, 1486 | "enabled":true 1487 | }, 1488 | { 1489 | "name":"bravia-dl-playstation-net", 1490 | "dest_addr":"bravia.dl.playstation.net", 1491 | "modes":[ 1492 | { 1493 | "port":80, 1494 | "mode":"http" 1495 | }, 1496 | { 1497 | "port":443, 1498 | "mode":"https" 1499 | } 1500 | ], 1501 | "catchall":false, 1502 | "enabled":true 1503 | }, 1504 | { 1505 | "name":"bravia-e-dl-playstation-net", 1506 | "dest_addr":"bravia-e.dl.playstation.net", 1507 | "modes":[ 1508 | { 1509 | "port":80, 1510 | "mode":"http" 1511 | }, 1512 | { 1513 | "port":443, 1514 | "mode":"https" 1515 | } 1516 | ], 1517 | "catchall":false, 1518 | "enabled":true 1519 | }, 1520 | { 1521 | "name":"bivl-netflix-com", 1522 | "dest_addr":"bivl.netflix.com", 1523 | "modes":[ 1524 | { 1525 | "port":443, 1526 | "mode":"https" 1527 | } 1528 | ], 1529 | "catchall":false, 1530 | "enabled":true 1531 | }, 1532 | { 1533 | "name":"bivl-pandora-com", 1534 | "dest_addr":"bivl.pandora.com", 1535 | "modes":[ 1536 | { 1537 | "port":80, 1538 | "mode":"http" 1539 | } 1540 | ], 1541 | "catchall":false, 1542 | "enabled":true 1543 | }, 1544 | { 1545 | "name":"netflix-htmltvui-api", 1546 | "dest_addr":"htmltvui-api.netflix.com", 1547 | "modes":[ 1548 | { 1549 | "port":80, 1550 | "mode":"http" 1551 | }, 1552 | { 1553 | "port":443, 1554 | "mode":"https" 1555 | } 1556 | ], 1557 | "catchall":false, 1558 | "enabled":true 1559 | }, 1560 | { 1561 | "name":"hlsioscwtv-warnerbros-com", 1562 | "dest_addr":"hlsioscwtv.warnerbros.com", 1563 | "modes":[ 1564 | { 1565 | "port":80, 1566 | "mode":"http" 1567 | } 1568 | ], 1569 | "catchall":false, 1570 | "enabled":true 1571 | }, 1572 | { 1573 | "name":"hbo.com", 1574 | "dest_addr":"hbo.com", 1575 | "modes":[ 1576 | { 1577 | "port":80, 1578 | "mode":"http" 1579 | }, 1580 | { 1581 | "port":443, 1582 | "mode":"https" 1583 | } 1584 | ], 1585 | "catchall":true, 1586 | "enabled":true 1587 | }, 1588 | { 1589 | "name":"www.hbo.com", 1590 | "dest_addr":"www.hbo.com", 1591 | "modes":[ 1592 | { 1593 | "port":80, 1594 | "mode":"http" 1595 | }, 1596 | { 1597 | "port":443, 1598 | "mode":"https" 1599 | } 1600 | ], 1601 | "catchall":true, 1602 | "enabled":true 1603 | }, 1604 | { 1605 | "name":"store.hbo.com", 1606 | "dest_addr":"store.hbo.com", 1607 | "modes":[ 1608 | { 1609 | "port":80, 1610 | "mode":"http" 1611 | }, 1612 | { 1613 | "port":443, 1614 | "mode":"https" 1615 | } 1616 | ], 1617 | "catchall":true, 1618 | "enabled":true 1619 | }, 1620 | { 1621 | "name":"itsh.bo", 1622 | "dest_addr":"itsh.bo", 1623 | "modes":[ 1624 | { 1625 | "port":80, 1626 | "mode":"http" 1627 | }, 1628 | { 1629 | "port":443, 1630 | "mode":"https" 1631 | } 1632 | ], 1633 | "catchall":true, 1634 | "enabled":true 1635 | }, 1636 | { 1637 | "name":"showtimeanytime.com", 1638 | "dest_addr":"showtimeanytime.com", 1639 | "modes":[ 1640 | { 1641 | "port":80, 1642 | "mode":"http" 1643 | }, 1644 | { 1645 | "port":443, 1646 | "mode":"https" 1647 | } 1648 | ], 1649 | "catchall":true, 1650 | "enabled":true 1651 | }, 1652 | { 1653 | "name":"www.showtimeanytime.com", 1654 | "dest_addr":"www.showtimeanytime.com", 1655 | "modes":[ 1656 | { 1657 | "port":80, 1658 | "mode":"http" 1659 | }, 1660 | { 1661 | "port":443, 1662 | "mode":"https" 1663 | } 1664 | ], 1665 | "catchall":true, 1666 | "enabled":true 1667 | }, 1668 | { 1669 | "name":"hbogo.com", 1670 | "dest_addr":"hbogo.com", 1671 | "modes":[ 1672 | { 1673 | "port":80, 1674 | "mode":"http" 1675 | }, 1676 | { 1677 | "port":443, 1678 | "mode":"https" 1679 | } 1680 | ], 1681 | "catchall":true, 1682 | "enabled":true 1683 | }, 1684 | { 1685 | "name":"www.hbogo.com", 1686 | "dest_addr":"www.hbogo.com", 1687 | "modes":[ 1688 | { 1689 | "port":80, 1690 | "mode":"http" 1691 | }, 1692 | { 1693 | "port":443, 1694 | "mode":"https" 1695 | } 1696 | ], 1697 | "catchall":true, 1698 | "enabled":true 1699 | }, 1700 | { 1701 | "name":"devicecast.hbogo.com", 1702 | "dest_addr":"devicecast.hbogo.com", 1703 | "modes":[ 1704 | { 1705 | "port":80, 1706 | "mode":"http" 1707 | }, 1708 | { 1709 | "port":443, 1710 | "mode":"https" 1711 | } 1712 | ], 1713 | "catchall":true, 1714 | "enabled":true 1715 | }, 1716 | { 1717 | "name":"catalog.lv3.hbogo.com", 1718 | "dest_addr":"catalog.lv3.hbogo.com", 1719 | "modes":[ 1720 | { 1721 | "port":80, 1722 | "mode":"http" 1723 | }, 1724 | { 1725 | "port":443, 1726 | "mode":"https" 1727 | } 1728 | ], 1729 | "catchall":true, 1730 | "enabled":true 1731 | }, 1732 | { 1733 | "name":"profile.hbogo.com", 1734 | "dest_addr":"profile.hbogo.com", 1735 | "modes":[ 1736 | { 1737 | "port":80, 1738 | "mode":"http" 1739 | }, 1740 | { 1741 | "port":443, 1742 | "mode":"https" 1743 | } 1744 | ], 1745 | "catchall":true, 1746 | "enabled":true 1747 | }, 1748 | { 1749 | "name":"pro.hbogo.com", 1750 | "dest_addr":"pro.hbogo.com", 1751 | "modes":[ 1752 | { 1753 | "port":80, 1754 | "mode":"http" 1755 | }, 1756 | { 1757 | "port":443, 1758 | "mode":"https" 1759 | } 1760 | ], 1761 | "catchall":true, 1762 | "enabled":true 1763 | }, 1764 | { 1765 | "name":"hls.hbo.lv3.hbogo.com", 1766 | "dest_addr":"hls.hbo.lv3.hbogo.com", 1767 | "modes":[ 1768 | { 1769 | "port":80, 1770 | "mode":"http" 1771 | }, 1772 | { 1773 | "port":443, 1774 | "mode":"https" 1775 | } 1776 | ], 1777 | "catchall":true, 1778 | "enabled":true 1779 | }, 1780 | { 1781 | "name":"i.hbo.lv3.hbogo.com", 1782 | "dest_addr":"i.hbo.lv3.hbogo.com", 1783 | "modes":[ 1784 | { 1785 | "port":80, 1786 | "mode":"http" 1787 | }, 1788 | { 1789 | "port":443, 1790 | "mode":"https" 1791 | } 1792 | ], 1793 | "catchall":true, 1794 | "enabled":true 1795 | }, 1796 | { 1797 | "name":"pdl.misc.lv3.hbogo.com", 1798 | "dest_addr":"pdl.misc.lv3.hbogo.com", 1799 | "modes":[ 1800 | { 1801 | "port":80, 1802 | "mode":"http" 1803 | }, 1804 | { 1805 | "port":443, 1806 | "mode":"https" 1807 | } 1808 | ], 1809 | "catchall":true, 1810 | "enabled":true 1811 | }, 1812 | { 1813 | "name":"smooth.misc.lv3.hbogo.com", 1814 | "dest_addr":"smooth.misc.lv3.hbogo.com", 1815 | "modes":[ 1816 | { 1817 | "port":80, 1818 | "mode":"http" 1819 | }, 1820 | { 1821 | "port":443, 1822 | "mode":"https" 1823 | } 1824 | ], 1825 | "catchall":true, 1826 | "enabled":true 1827 | }, 1828 | { 1829 | "name":"smooth.pro17.lv3.hbogo.com", 1830 | "dest_addr":"smooth.pro17.lv3.hbogo.com", 1831 | "modes":[ 1832 | { 1833 | "port":80, 1834 | "mode":"http" 1835 | }, 1836 | { 1837 | "port":443, 1838 | "mode":"https" 1839 | } 1840 | ], 1841 | "catchall":true, 1842 | "enabled":true 1843 | }, 1844 | { 1845 | "name":"reporting.hbogo.com", 1846 | "dest_addr":"reporting.hbogo.com", 1847 | "modes":[ 1848 | { 1849 | "port":80, 1850 | "mode":"http" 1851 | }, 1852 | { 1853 | "port":443, 1854 | "mode":"https" 1855 | } 1856 | ], 1857 | "catchall":true, 1858 | "enabled":true 1859 | }, 1860 | { 1861 | "name":"register.hbogo.com", 1862 | "dest_addr":"register.hbogo.com", 1863 | "modes":[ 1864 | { 1865 | "port":80, 1866 | "mode":"http" 1867 | }, 1868 | { 1869 | "port":443, 1870 | "mode":"https" 1871 | } 1872 | ], 1873 | "catchall":true, 1874 | "enabled":true 1875 | }, 1876 | { 1877 | "name":"southpark.cc.com", 1878 | "dest_addr":"southpark.cc.com", 1879 | "modes":[ 1880 | { 1881 | "port":80, 1882 | "mode":"http" 1883 | }, 1884 | { 1885 | "port":443, 1886 | "mode":"https" 1887 | } 1888 | ], 1889 | "catchall":true, 1890 | "enabled":true 1891 | }, 1892 | { 1893 | "name":"hulu.com", 1894 | "dest_addr":"hulu.com", 1895 | "modes":[ 1896 | { 1897 | "port":80, 1898 | "mode":"http" 1899 | }, 1900 | { 1901 | "port":443, 1902 | "mode":"https" 1903 | } 1904 | ], 1905 | "catchall":true, 1906 | "enabled":true 1907 | }, 1908 | { 1909 | "name":"www.hulu.com", 1910 | "dest_addr":"www.hulu.com", 1911 | "modes":[ 1912 | { 1913 | "port":80, 1914 | "mode":"http" 1915 | }, 1916 | { 1917 | "port":443, 1918 | "mode":"https" 1919 | } 1920 | ], 1921 | "catchall":true, 1922 | "enabled":true 1923 | }, 1924 | { 1925 | "name":"secure.hulu.com", 1926 | "dest_addr":"secure.hulu.com", 1927 | "modes":[ 1928 | { 1929 | "port":80, 1930 | "mode":"http" 1931 | }, 1932 | { 1933 | "port":443, 1934 | "mode":"https" 1935 | } 1936 | ], 1937 | "catchall":true, 1938 | "enabled":true 1939 | }, 1940 | { 1941 | "name":"netflix.com", 1942 | "dest_addr":"netflix.com", 1943 | "modes":[ 1944 | { 1945 | "port":80, 1946 | "mode":"http" 1947 | }, 1948 | { 1949 | "port":443, 1950 | "mode":"https" 1951 | } 1952 | ], 1953 | "catchall":true, 1954 | "enabled":true 1955 | }, 1956 | { 1957 | "name":"pandora.com", 1958 | "dest_addr":"pandora.com", 1959 | "modes":[ 1960 | { 1961 | "port":80, 1962 | "mode":"http" 1963 | }, 1964 | { 1965 | "port":443, 1966 | "mode":"https" 1967 | } 1968 | ], 1969 | "catchall":true, 1970 | "enabled":true 1971 | }, 1972 | { 1973 | "name":"scee-vidzone-tv", 1974 | "dest_addr":"scee.vidzone.tv", 1975 | "modes":[ 1976 | { 1977 | "port":80, 1978 | "mode":"http" 1979 | }, 1980 | { 1981 | "port":443, 1982 | "mode":"https" 1983 | } 1984 | ], 1985 | "catchall":false, 1986 | "enabled":true 1987 | }, 1988 | { 1989 | "name":"sceeassets-vidzone-tv", 1990 | "dest_addr":"sceeassets.vidzone.tv", 1991 | "modes":[ 1992 | { 1993 | "port":80, 1994 | "mode":"http" 1995 | }, 1996 | { 1997 | "port":443, 1998 | "mode":"https" 1999 | } 2000 | ], 2001 | "catchall":false, 2002 | "enabled":true 2003 | }, 2004 | { 2005 | "name":"ps4-api-us-crackle-com", 2006 | "dest_addr":"ps4-api-us.crackle.com", 2007 | "modes":[ 2008 | { 2009 | "port":80, 2010 | "mode":"http" 2011 | }, 2012 | { 2013 | "port":443, 2014 | "mode":"https" 2015 | } 2016 | ], 2017 | "catchall":false, 2018 | "enabled":true 2019 | }, 2020 | { 2021 | "name":"apiv2-vevo-com", 2022 | "dest_addr":"apiv2.vevo.com", 2023 | "modes":[ 2024 | { 2025 | "port":80, 2026 | "mode":"http" 2027 | }, 2028 | { 2029 | "port":443, 2030 | "mode":"https" 2031 | } 2032 | ], 2033 | "catchall":false, 2034 | "enabled":true 2035 | } 2036 | ] 2037 | } 2038 | -------------------------------------------------------------------------------- /genconf.php: -------------------------------------------------------------------------------- 1 | json_clean_decode($content); 13 | $iptables_location = $json->iptables_location; 14 | $server_options = $json->server_options; 15 | $haproxy_bind_ip = $json->haproxy_bind_ip; 16 | $dnsmasq_content = ''; 17 | 18 | $haproxy_content = $this->generate_global(); 19 | $haproxy_content .= $this->generate_defaults(); 20 | 21 | $haproxy_catchall_frontend_content = $this->generate_frontend('catchall', 'http', $haproxy_bind_ip, 80, TRUE); 22 | $haproxy_catchall_backend_content = $this->generate_backend('catchall', 'http', NULL, NULL, NULL, TRUE); 23 | 24 | $haproxy_catchall_frontend_ssl_content = $this->generate_frontend('catchall', 'https', $haproxy_bind_ip, 443, TRUE); 25 | $haproxy_catchall_backend_ssl_content = $this->generate_backend('catchall', 'https', NULL, NULL, NULL, TRUE); 26 | 27 | if ($json->stats->enabled) { 28 | $haproxy_content .= $this->generate_stats($json->stats, $haproxy_bind_ip); 29 | } 30 | 31 | while ($proxy = array_shift($json->proxies)) { 32 | if ($proxy->enabled) { 33 | while ($mode = array_shift($proxy->modes)) { 34 | if ($mode->mode === 'http') { 35 | $haproxy_catchall_frontend_content .= $this->generate_frontend_catchall_entry($proxy->dest_addr, $mode->mode); 36 | $haproxy_catchall_backend_content .= $this->generate_backend_catchall_entry($proxy->dest_addr, $mode->mode, $mode->port, 37 | $server_options); 38 | } 39 | else if ($mode->mode === 'https') { 40 | $haproxy_catchall_frontend_ssl_content .= $this->generate_frontend_catchall_entry($proxy->dest_addr, $mode->mode); 41 | $haproxy_catchall_backend_ssl_content .= $this->generate_backend_catchall_entry($proxy->dest_addr, $mode->mode, $mode->port, 42 | $server_options); 43 | } 44 | } 45 | $dnsmasq_content .= $this->generate_dns($proxy->dest_addr, $haproxy_bind_ip); 46 | } 47 | } 48 | 49 | $test = $this->add_test($haproxy_bind_ip, $server_options); 50 | $haproxy_catchall_frontend_content .= $test[0]; 51 | $haproxy_catchall_backend_content .= $test[1]; 52 | $dnsmasq_content .= $test[2]; 53 | 54 | $haproxy_content .= $haproxy_catchall_frontend_content . PHP_EOL; 55 | $haproxy_content .= $haproxy_catchall_backend_content; 56 | $haproxy_content .= $haproxy_catchall_frontend_ssl_content . PHP_EOL; 57 | $haproxy_content .= $haproxy_catchall_backend_ssl_content; 58 | 59 | $haproxy_content .= $this->generate_deadend('http'); 60 | $haproxy_content .= $this->generate_deadend('https'); 61 | 62 | echo 'If you are using an inbound firewall on ' . $haproxy_bind_ip . ':' . PHP_EOL; 63 | if ($json->stats->enabled) { 64 | echo $iptables_location . ' -A INPUT -p tcp -m state --state NEW -d ' . $haproxy_bind_ip . ' --dport ' . $json->stats->port . ' -j ACCEPT' . PHP_EOL; 65 | } 66 | echo $iptables_location . ' -A INPUT -p tcp -m state --state NEW -m multiport -d ' . $haproxy_bind_ip . ' --dports ' . 80 . ':' . 67 | 443 . ' -j ACCEPT' . PHP_EOL; 68 | echo PHP_EOL; 69 | 70 | file_put_contents($haproxy_out_filename, $haproxy_content); 71 | echo 'File generated: ' . $haproxy_out_filename . PHP_EOL; 72 | 73 | file_put_contents($dnsmasq_out_filename, $dnsmasq_content); 74 | echo 'File generated: ' . $dnsmasq_out_filename . PHP_EOL; 75 | 76 | echo PHP_EOL; 77 | echo '***********************************************************************************************' . PHP_EOL; 78 | echo 'Caution: it\'s not recommended but it\'s possible to run a (recursive) DNS forwarder on your' . PHP_EOL; 79 | echo 'remote server ' . $haproxy_bind_ip . '. If you leave the DNS port wide open to everyone,' . PHP_EOL; 80 | echo 'your server will get terminated sooner or later because of abuse (DDoS amplification attacks).' . PHP_EOL; 81 | echo '***********************************************************************************************' . PHP_EOL; 82 | 83 | } 84 | 85 | function create_non_sni_config($json_in_filename, $haproxy_out_filename = 'haproxy.conf', $dnsmasq_out_filename = 'dnsmasq-haproxy.conf', $iptables_out_filename = 'iptables-haproxy.sh') { 86 | $content = file_get_contents($json_in_filename); 87 | $json = $this->json_clean_decode($content); 88 | $iptables_location = $json->iptables_location; 89 | $server_options = $json->server_options; 90 | $haproxy_bind_ip = $json->haproxy_bind_ip; 91 | $dnsmasq_content = ''; 92 | $iptables_content = ''; 93 | 94 | $haproxy_content = $this->generate_global(); 95 | $haproxy_content .= $this->generate_defaults(); 96 | 97 | $current_dnat_ip = $json->dnat_base_ip; 98 | $current_dnat_port = $json->dnat_base_port; 99 | 100 | $haproxy_catchall_frontend_content = $this->generate_frontend('catchall', 'http', $haproxy_bind_ip, $current_dnat_port, TRUE); 101 | $haproxy_catchall_backend_content = $this->generate_backend('catchall', 'http', NULL, NULL, NULL, TRUE); 102 | 103 | $haproxy_catchall_frontend_ssl_content = $this->generate_frontend('catchall', 'https', $haproxy_bind_ip, $current_dnat_port + 1, TRUE); 104 | $haproxy_catchall_backend_ssl_content = $this->generate_backend('catchall', 'https', NULL, NULL, NULL, TRUE); 105 | 106 | if ($json->stats->enabled) { 107 | $haproxy_content .= $this->generate_stats($json->stats, $haproxy_bind_ip); 108 | } 109 | 110 | while ($proxy = array_shift($json->proxies)) { 111 | if ($proxy->enabled && $proxy->catchall) { 112 | while ($mode = array_shift($proxy->modes)) { 113 | if ($mode->mode === 'http') { 114 | $haproxy_catchall_frontend_content .= $this->generate_frontend_catchall_entry($proxy->dest_addr, $mode->mode); 115 | $haproxy_catchall_backend_content .= $this->generate_backend_catchall_entry($proxy->dest_addr, $mode->mode, $mode->port, 116 | $server_options); 117 | } 118 | else if ($mode->mode === 'https') { 119 | $haproxy_catchall_frontend_ssl_content .= $this->generate_frontend_catchall_entry($proxy->dest_addr, $mode->mode); 120 | $haproxy_catchall_backend_ssl_content .= $this->generate_backend_catchall_entry($proxy->dest_addr, $mode->mode, $mode->port, 121 | $server_options); 122 | } 123 | } 124 | $dnsmasq_content .= $this->generate_dns($proxy->dest_addr, $current_dnat_ip); 125 | } 126 | } 127 | 128 | $test = $this->add_test($current_dnat_ip, $server_options); 129 | $haproxy_catchall_frontend_content .= $test[0]; 130 | $haproxy_catchall_backend_content .= $test[1]; 131 | $dnsmasq_content .= $test[2]; 132 | 133 | echo 'Make sure the following IP addresses are available as virtual interfaces on your Ddnsmasq-server:' . PHP_EOL; 134 | 135 | $haproxy_content .= $haproxy_catchall_frontend_content . PHP_EOL; 136 | $haproxy_content .= $haproxy_catchall_backend_content; 137 | $haproxy_content .= $haproxy_catchall_frontend_ssl_content . PHP_EOL; 138 | $haproxy_content .= $haproxy_catchall_backend_ssl_content; 139 | $iptables_content .= $this->generate_iptables('80', $haproxy_bind_ip, $current_dnat_ip, $current_dnat_port, $iptables_location); 140 | $current_dnat_port++; 141 | $iptables_content .= $this->generate_iptables('443', $haproxy_bind_ip, $current_dnat_ip, $current_dnat_port, $iptables_location); 142 | $current_dnat_port++; 143 | echo $current_dnat_ip . PHP_EOL; 144 | 145 | $json = $this->json_clean_decode($content); 146 | while ($proxy = array_shift($json->proxies)) { 147 | if ($proxy->enabled && ! $proxy->catchall) { 148 | $current_dnat_ip = long2ip(ip2long($current_dnat_ip) + 1); 149 | while ($mode = array_shift($proxy->modes)) { 150 | $haproxy_content .= $this->generate_frontend($proxy->name, $mode->mode, $haproxy_bind_ip, $current_dnat_port, FALSE); 151 | $iptables_content .= $this->generate_iptables($mode->port, $haproxy_bind_ip, $current_dnat_ip, $current_dnat_port, 152 | $iptables_location); 153 | $haproxy_content .= $this->generate_backend($proxy->name, $mode->mode, $proxy->dest_addr, $mode->port, $server_options, FALSE); 154 | $current_dnat_port++; 155 | } 156 | $dnsmasq_content .= $this->generate_dns($proxy->dest_addr, $current_dnat_ip); 157 | echo $current_dnat_ip . PHP_EOL; 158 | } 159 | } 160 | 161 | $haproxy_content .= $this->generate_deadend('http'); 162 | $haproxy_content .= $this->generate_deadend('https'); 163 | 164 | echo PHP_EOL; 165 | echo 'If you are using an inbound firewall on ' . $haproxy_bind_ip . ':' . PHP_EOL; 166 | if ($json->stats->enabled) { 167 | echo $iptables_location . ' -A INPUT -p tcp -m state --state NEW -d ' . $haproxy_bind_ip . ' --dport ' . $json->stats->port . ' -j ACCEPT' . PHP_EOL; 168 | } 169 | echo $iptables_location . ' -A INPUT -p tcp -m state --state NEW -m multiport -d ' . $haproxy_bind_ip . ' --dports ' . $json->dnat_base_port . ':' . 170 | --$current_dnat_port . ' -j ACCEPT' . PHP_EOL; 171 | echo PHP_EOL; 172 | 173 | file_put_contents($haproxy_out_filename, $haproxy_content); 174 | echo 'File generated: ' . $haproxy_out_filename . PHP_EOL; 175 | 176 | file_put_contents($dnsmasq_out_filename, $dnsmasq_content); 177 | echo 'File generated: ' . $dnsmasq_out_filename . PHP_EOL; 178 | 179 | file_put_contents($iptables_out_filename, $iptables_content); 180 | echo 'File generated: ' . $iptables_out_filename . PHP_EOL; 181 | } 182 | 183 | function create_local_non_sni_config($json_in_filename, $haproxy_out_filename = 'haproxy.conf', $netsh_out_filename = 'netsh-haproxy.cmd', $hosts_out_filename = 'hosts-haproxy.txt', $rinetd_out_filename = 'rinetd-haproxy.conf') { 184 | $content = file_get_contents($json_in_filename); 185 | $json = $this->json_clean_decode($content); 186 | $iptables_location = $json->iptables_location; 187 | $server_options = $json->server_options; 188 | $haproxy_bind_ip = $json->haproxy_bind_ip; 189 | $netsh_content = ''; 190 | $rinetd_content = ''; 191 | $hosts = array(); 192 | 193 | $haproxy_content = $this->generate_global(); 194 | $haproxy_content .= $this->generate_defaults(); 195 | 196 | $current_loopback_ip = $json->loopback_base_ip; 197 | $current_dnat_port = $json->dnat_base_port; 198 | 199 | $haproxy_catchall_frontend_content = $this->generate_frontend('catchall', 'http', $haproxy_bind_ip, $current_dnat_port, TRUE); 200 | $haproxy_catchall_backend_content = $this->generate_backend('catchall', 'http', NULL, NULL, NULL, TRUE); 201 | 202 | $haproxy_catchall_frontend_ssl_content = $this->generate_frontend('catchall', 'https', $haproxy_bind_ip, $current_dnat_port + 1, TRUE); 203 | $haproxy_catchall_backend_ssl_content = $this->generate_backend('catchall', 'https', NULL, NULL, NULL, TRUE); 204 | 205 | if ($json->stats->enabled) { 206 | $haproxy_content .= $this->generate_stats($json->stats, $haproxy_bind_ip); 207 | } 208 | 209 | while ($proxy = array_shift($json->proxies)) { 210 | if ($proxy->enabled && $proxy->catchall) { 211 | while ($mode = array_shift($proxy->modes)) { 212 | if ($mode->mode === 'http') { 213 | $haproxy_catchall_frontend_content .= $this->generate_frontend_catchall_entry($proxy->dest_addr, $mode->mode); 214 | $haproxy_catchall_backend_content .= $this->generate_backend_catchall_entry($proxy->dest_addr, $mode->mode, $mode->port, 215 | $server_options); 216 | } 217 | else if ($mode->mode === 'https') { 218 | $haproxy_catchall_frontend_ssl_content .= $this->generate_frontend_catchall_entry($proxy->dest_addr, $mode->mode); 219 | $haproxy_catchall_backend_ssl_content .= $this->generate_backend_catchall_entry($proxy->dest_addr, $mode->mode, $mode->port, 220 | $server_options); 221 | } 222 | } 223 | $this->add_hosts($hosts, $proxy->dest_addr, $current_loopback_ip); 224 | } 225 | } 226 | 227 | $test = $this->add_test($current_loopback_ip, $server_options); 228 | $haproxy_catchall_frontend_content .= $test[0]; 229 | $haproxy_catchall_backend_content .= $test[1]; 230 | $this->add_hosts($hosts, 'proxy-test.trick77.com', $current_loopback_ip); 231 | $this->add_hosts($hosts, 'dns-test.trick77.com', $current_loopback_ip); 232 | 233 | $haproxy_content .= $haproxy_catchall_frontend_content . PHP_EOL; 234 | $haproxy_content .= $haproxy_catchall_backend_content; 235 | $haproxy_content .= $haproxy_catchall_frontend_ssl_content . PHP_EOL; 236 | $haproxy_content .= $haproxy_catchall_backend_ssl_content; 237 | $netsh_content .= $this->generate_netsh('80', $haproxy_bind_ip, $current_loopback_ip, $current_dnat_port); 238 | $rinetd_content .= $this->generate_rinetd('80', $haproxy_bind_ip, $current_loopback_ip, $current_dnat_port); 239 | $current_dnat_port++; 240 | $netsh_content .= $this->generate_netsh('443', $haproxy_bind_ip, $current_loopback_ip, $current_dnat_port); 241 | $rinetd_content .= $this->generate_rinetd('443', $haproxy_bind_ip, $current_loopback_ip, $current_dnat_port); 242 | $current_dnat_port++; 243 | 244 | $json = $this->json_clean_decode($content); 245 | while ($proxy = array_shift($json->proxies)) { 246 | if ($proxy->enabled && ! $proxy->catchall) { 247 | $current_loopback_ip = long2ip(ip2long($current_loopback_ip) + 1); 248 | while ($mode = array_shift($proxy->modes)) { 249 | $haproxy_content .= $this->generate_frontend($proxy->name, $mode->mode, $haproxy_bind_ip, $current_dnat_port, FALSE); 250 | $netsh_content .= $this->generate_netsh($mode->port, $haproxy_bind_ip, $current_loopback_ip, $current_dnat_port); 251 | $rinetd_content .= $this->generate_rinetd($mode->port, $haproxy_bind_ip, $current_loopback_ip, $current_dnat_port); 252 | $haproxy_content .= $this->generate_backend($proxy->name, $mode->mode, $proxy->dest_addr, $mode->port, $server_options, FALSE); 253 | $current_dnat_port++; 254 | } 255 | $this->add_hosts($hosts, $proxy->dest_addr, $current_loopback_ip); 256 | } 257 | } 258 | 259 | $haproxy_content .= $this->generate_deadend('http'); 260 | $haproxy_content .= $this->generate_deadend('https'); 261 | 262 | echo 'If you are using an inbound firewall on ' . $haproxy_bind_ip . ':' . PHP_EOL; 263 | if ($json->stats->enabled) { 264 | echo $iptables_location . ' -A INPUT -p tcp -m state --state NEW -d ' . $haproxy_bind_ip . ' --dport ' . $json->stats->port . ' -j ACCEPT' . PHP_EOL; 265 | } 266 | echo $iptables_location . ' -A INPUT -p tcp -m state --state NEW -m multiport -d ' . $haproxy_bind_ip . ' --dports ' . $json->dnat_base_port . ':' . 267 | --$current_dnat_port . ' -j ACCEPT' . PHP_EOL; 268 | echo PHP_EOL; 269 | 270 | file_put_contents($haproxy_out_filename, $haproxy_content); 271 | echo 'File generated: ' . $haproxy_out_filename . PHP_EOL; 272 | 273 | file_put_contents($hosts_out_filename, $this->generate_hosts_content($hosts)); 274 | echo 'File generated: ' . $hosts_out_filename . PHP_EOL; 275 | 276 | file_put_contents($netsh_out_filename, $netsh_content); 277 | echo 'File generated: ' . $netsh_out_filename . PHP_EOL; 278 | 279 | file_put_contents($rinetd_out_filename, $rinetd_content); 280 | echo 'File generated: ' . $rinetd_out_filename . PHP_EOL; 281 | } 282 | 283 | function add_test($catchall_ip, $server_options) { 284 | $haproxy_catchall_frontend_content = $this->generate_frontend_catchall_entry('proxy-test.trick77.com', 'http'); 285 | $haproxy_catchall_backend_content = $this->generate_backend_catchall_entry('proxy-test.trick77.com', 'http', '80', 286 | $server_options, 'trick77.com'); 287 | $dnsmasq_content = $this->generate_dns('proxy-test.trick77.com', $catchall_ip); 288 | $dnsmasq_content .= $this->generate_dns('dns-test.trick77.com', $catchall_ip); 289 | return array($haproxy_catchall_frontend_content, $haproxy_catchall_backend_content, $dnsmasq_content); 290 | } 291 | 292 | function generate_frontend_catchall_entry($dest_addr, $mode) { 293 | if ($mode === 'http') { 294 | return $this->format('use_backend b_catchall_' . $mode . ' if { hdr_dom(host) -i ' . $dest_addr . ' }'); 295 | } 296 | else if ($mode === 'https') { 297 | return $this->format('use_backend b_catchall_' . $mode . ' if { req_ssl_sni -i ' . $dest_addr . ' }'); 298 | } 299 | return NULL; 300 | } 301 | 302 | function generate_backend_catchall_entry($dest_addr, $mode, $port, $server_options, $override_dest_addr = NULL) { 303 | $result = NULL; 304 | if ($mode === 'http') { 305 | $result = $this->format('use-server ' . $dest_addr . ' if { hdr_dom(host) -i ' . $dest_addr . ' }'); 306 | if ($override_dest_addr == NULL) { 307 | $result .= $this->format('server ' . $dest_addr . ' ' . $dest_addr . ':' . $port . ' ' . $server_options . PHP_EOL); 308 | } 309 | else { 310 | $result .= $this->format('server ' . $dest_addr . ' ' . $override_dest_addr . ':' . $port . ' ' . $server_options . PHP_EOL); 311 | } 312 | } 313 | else if ($mode === 'https') { 314 | $result = $this->format('use-server ' . $dest_addr . ' if { req_ssl_sni -i ' . $dest_addr . ' }'); 315 | $result .= $this->format('server ' . $dest_addr . ' ' . $dest_addr . ':' . $port . ' ' . $server_options . PHP_EOL); 316 | } 317 | return $result; 318 | } 319 | 320 | function generate_dns($dest_addr, $current_dnat_ip) { 321 | $result = 'address=/' . $dest_addr . '/' . $current_dnat_ip; 322 | return $result . PHP_EOL; 323 | } 324 | 325 | function add_hosts(&$hosts, $dest_addr, $current_loopback_ip) { 326 | if(isset($hosts[$current_loopback_ip])) { 327 | array_push($hosts[$current_loopback_ip], $dest_addr); 328 | } else { 329 | $hosts[$current_loopback_ip] = [$dest_addr]; 330 | } 331 | } 332 | 333 | function generate_netsh($port, $haproxy_bind_ip, $current_loopback_ip, $current_dnat_port) { 334 | $result = 'netsh interface portproxy add v4tov4 protocol=tcp listenport=' . $port . ' listenaddress=' . $current_loopback_ip . ' connectaddress=' . 335 | $haproxy_bind_ip . ' connectport=' . $current_dnat_port . PHP_EOL; 336 | return $result; 337 | } 338 | 339 | function generate_rinetd($port, $haproxy_bind_ip, $current_loopback_ip, $current_dnat_port) { 340 | $result = $current_loopback_ip . ' ' . $port . ' ' . $haproxy_bind_ip . ' ' . $current_dnat_port . PHP_EOL; 341 | return $result; 342 | } 343 | 344 | function generate_hosts_content(&$hosts) { 345 | $result = ''; 346 | foreach ($hosts as $ip => $list) { 347 | $result .= $ip . ' ' . implode(' ',$list) . ' ### GENERATED ' .PHP_EOL; 348 | } 349 | return $result; 350 | } 351 | 352 | function generate_iptables($port, $haproxy_bind_ip, $current_dnat_ip, $current_dnat_port, $iptables_location) { 353 | $result = $iptables_location . ' -t nat -A PREROUTING -p tcp --dport ' . $port . ' -d ' . $current_dnat_ip . ' -j DNAT --to-destination ' . 354 | $haproxy_bind_ip . ':' . $current_dnat_port . PHP_EOL; 355 | $result .= $iptables_location . ' -t nat -A POSTROUTING -p tcp --dport ' . $current_dnat_port . ' -j MASQUERADE' . PHP_EOL; 356 | return $result; 357 | } 358 | 359 | function generate_global() { 360 | $result = $this->format('global', FALSE); 361 | $result .= $this->format('daemon'); 362 | $result .= $this->format('maxconn 20000'); 363 | $result .= $this->format('user haproxy'); 364 | $result .= $this->format('group haproxy'); 365 | $result .= $this->format('stats socket /var/run/haproxy.sock mode 0600 level admin'); 366 | $result .= $this->format('log /dev/log local0 debug'); 367 | $result .= $this->format('pidfile /var/run/haproxy.pid'); 368 | $result .= $this->format('spread-checks 5'); 369 | $result .= PHP_EOL; 370 | return $result; 371 | } 372 | 373 | function generate_defaults() { 374 | $result = $this->format('defaults', FALSE); 375 | $result .= $this->format('maxconn 19500'); 376 | $result .= $this->format('log global'); 377 | $result .= $this->format('mode http'); 378 | $result .= $this->format('option httplog'); 379 | $result .= $this->format('option abortonclose'); 380 | $result .= $this->format('option http-server-close'); 381 | $result .= $this->format('option persist'); 382 | $result .= $this->format('timeout connect 20s'); 383 | $result .= $this->format('timeout client 120s'); 384 | $result .= $this->format('timeout server 120s'); 385 | $result .= $this->format('timeout queue 120s'); 386 | $result .= $this->format('timeout check 10s'); 387 | $result .= $this->format('retries 3'); 388 | $result .= PHP_EOL; 389 | return $result; 390 | } 391 | 392 | function generate_deadend($mode) { 393 | $result = $this->format('backend b_deadend_' . $mode, FALSE); 394 | if ($mode === 'http') { 395 | $result .= $this->format('mode http'); 396 | $result .= $this->format('option httplog'); 397 | $result .= $this->format('option accept-invalid-http-response'); 398 | $result .= $this->format('option http-server-close'); 399 | } 400 | else if ($mode === 'https') { 401 | $result .= $this->format('mode tcp'); 402 | $result .= $this->format('option tcplog'); 403 | } 404 | 405 | $result .= PHP_EOL; 406 | return $result; 407 | } 408 | 409 | function generate_stats($stats, $haproxy_bind_ip) { 410 | $result = $this->format('listen stats', FALSE); 411 | $result .= $this->format('bind ' . $haproxy_bind_ip . ':' . $stats->port); 412 | $result .= $this->format('mode http'); 413 | $result .= $this->format('stats enable'); 414 | $result .= $this->format('stats realm Protected\\ Area'); 415 | $result .= $this->format('stats uri /'); 416 | $result .= $this->format('stats auth ' . $stats->user . ':' . $stats->password); 417 | $result .= PHP_EOL; 418 | return $result; 419 | } 420 | 421 | function generate_frontend($proxy_name, $mode, $haproxy_bind_ip, $current_dnat_port, $is_catchall) { 422 | $result = $this->format('frontend f_' . $proxy_name . '_' . $mode, FALSE); 423 | $result .= $this->format('bind ' . $haproxy_bind_ip . ':' . $current_dnat_port); 424 | 425 | if ($mode === 'http') { 426 | $result .= $this->format('mode http'); 427 | $result .= $this->format('option httplog'); 428 | $result .= $this->format('capture request header Host len 50'); 429 | $result .= $this->format('capture request header User-Agent len 150'); 430 | } 431 | else if ($mode === 'https') { 432 | $result .= $this->format('mode tcp'); 433 | $result .= $this->format('option tcplog'); 434 | if ($is_catchall) { 435 | $result .= $this->format('tcp-request inspect-delay 5s'); 436 | $result .= $this->format('tcp-request content accept if { req_ssl_hello_type 1 }'); 437 | } 438 | } 439 | if ($is_catchall) { 440 | $result .= $this->format('default_backend b_deadend_' . $mode); 441 | } 442 | else { 443 | $result .= $this->format('default_backend b_' . $proxy_name . '_' . $mode); 444 | } 445 | $result .= PHP_EOL; 446 | return $result; 447 | } 448 | 449 | function generate_backend($proxy_name, $mode, $dest_addr, $port, $server_options, $is_catchall) { 450 | $result = $this->format('backend b_' . $proxy_name . '_' . $mode, FALSE); 451 | 452 | if ($mode === 'http') { 453 | $result .= $this->format('mode http'); 454 | $result .= $this->format('option httplog'); 455 | $result .= $this->format('option accept-invalid-http-response'); 456 | 457 | } 458 | else if ($mode === 'https') { 459 | $result .= $this->format('mode tcp'); 460 | $result .= $this->format('option tcplog'); 461 | } 462 | 463 | if (! $is_catchall) { 464 | $result .= $this->format('server ' . $dest_addr . ' ' . $dest_addr . ':' . $port . ' ' . $server_options); 465 | } 466 | return $result . PHP_EOL; 467 | } 468 | 469 | function format($line, $do_ident = TRUE) { 470 | if ($do_ident) { 471 | return $this->INDENT . $line . PHP_EOL; 472 | } 473 | return $line . PHP_EOL; 474 | } 475 | 476 | function json_clean_decode($json, $assoc = false, $depth = 512, $options = 0) { 477 | $json = preg_replace("#(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|([\s\t]//.*)|(^//.*)#", '', $json); 478 | if(version_compare(phpversion(), '5.4.0', '>=')) { 479 | $json = json_decode($json, $assoc, $depth, $options); 480 | } 481 | elseif(version_compare(phpversion(), '5.3.0', '>=')) { 482 | $json = json_decode($json, $assoc, $depth); 483 | } 484 | else { 485 | $json = json_decode($json, $assoc); 486 | } 487 | 488 | return $json; 489 | } 490 | 491 | } 492 | 493 | if ($argc >= 2) { 494 | $g = new GenConf(); 495 | $arg1 = strtolower($argv[1]); 496 | if ($arg1 === 'non-sni') { 497 | $g->create_non_sni_config('config.json'); 498 | } else if ($arg1 === 'local') { 499 | $g->create_local_non_sni_config('config.json'); 500 | } else if ($arg1 === 'pure-sni') { 501 | $g->create_pure_sni_config('config.json'); 502 | } else { 503 | die("Missing/wrong argument, use pure-sni (simple setup), non-sni (advanced setup), local (advanced setup)" . PHP_EOL); 504 | } 505 | } 506 | else { 507 | die("Missing/wrong argument, use pure-sni (simple setup), non-sni (advanced setup), local (advanced setup)" . PHP_EOL); 508 | } 509 | ?> 510 | --------------------------------------------------------------------------------