What's new
  • Welcome to PHCorner Forums. Take a moment to Sign up and gain unlimited access and extra privileges that guests are not entitled to, such as: All that and more! Registration is quick, simple and absolutely free. Join our community today!

Help WIKI ng mga captive portal bypass

prinzrainer

Journeyman
Joined
Jan 12, 2019
Messages
75
Reaction score
53
Age
19
, Last edited:
Mga ka phc gawa po tayo ng wiki kung paano mag bypass for free internet.

1. HTTP-PROXY (WORKING)
Some how na aallow ng ISP yung HTTP CONNECT na to:
580173
Pag mali yung payload na to mag iinject ng 302 na response yung ISP.

Working parin yung tinatawag nilang BACK-INJECT, BACK-QUERY method.
So ano po yung method na yun?
To summarize:
Front Inject: Huli yung CONNECT na header.
Back Inject: Una yung CONNECT na header.
Front Query: Una yung host huli yung proxy.
Back Query: Una yung proxy huli yung host.

So ano yung itsura ng boung http Request?
(windows line ending)
Code:
CONNECT 13.229.240.113:443@viber.com HTTP/1.0

POST https://viber.com HTTP/1.0
Host: viber.com
X-Online-Host: viber.com
X-Forward-Host: viber.com
601652

Ano yung hitsura ng call flow?
PlantUML Diagram


Since di supported ng OpenVPN ang back inject, kailangan parin nating gamitan ng ForwardingServer (see in point 2).
Pero instead na mag ssend tayo ng fake SNI yung fake HTTP Request naman yung e ssend natin.
Diff:
-    tosock.send("16030100dd010000d90303524408300450b48f90ead85d002384a64b6c1dc570ffd1e0aca36728f3a3fff7000042c030c02cc028c024c014c00ac032c02ec02ac026c00fc005009d003d00350084c02fc02bc027c023c013c009c031c02dc029c025c00ec004009c003c002f004100ff0100006e00000015001300001070672e63646e2e76696265722e636f6d000b000403000102000a001c001a00170019001c001b0018001a0016000e000d000b000c0009000a00230000000d0020001e060106020603050105020503040104020403030103020303020102020203000f000101".decode("hex"))
+    tosock.send("CONNECT 13.229.240.113:443@viber.com HTTP/1.0\r\n\r\n" +
+                "POST https://viber.com HTTP/1.0\r\n" +
+                "Host: viber.com\r\n" +
+                "X-Online-Host: viber.com\r\n" +
+                "X-Forward-Host: viber.com\r\n\r\n")
2. TLS FAKE SNI (NOT WORKING AS OF 00:16 26/04/2019)
During TLS handshake binibigay ng client kung ano yung server name ng pag coconnectan. Ito din yung ginagamit ng isp pang filter kung ok ba yung inacess mo.
kung di tanggap ng isp yung SNI mo mag iinject lang to ng TCP RESET.
580176
Sa SUN working pa ata to?
Information sa ibang network?

Additional Information:

Di gumagana sa AWS Lightsail, failed na sa TCP Handshake palang. Parang blocked ata yung HTTPS port ng AWS pag walang load. Na try ko yung ibang IP (from unityvpn) nag coconnected naman.

Working na yung lighsail turns out na mali lang pala yung bind address na nalagay ko.
Yung call flow nya is parang ganito:

580910

LocalForwardingServer.py
Python:
#!/usr/bin/python

import socket
import time
import threading

# Adress kung saan naka run yung LocalForwardingServer
# Usually mag rurun to same machine ng OpenVPN Client
# So pweding 127.0.0.1 lang

LOCAL_SERVER_ADDRESS = ('XXX.XXX.XXX.XXX', 443)

# Address kung saan naka run yung RemoteForwardingServer
# Usually mag rurun to same machine ng OpenVPN Server
# Dapat di naka block sa firewall ng server yung 443
REMOTE_SERVER_ADDRESS = ("XXX.XXX.XXX.XXX", 443)

tosock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
fromlisten = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
fromlisten.bind(LOCAL_SERVER_ADDRESS)
fromlisten.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
fromlisten.listen(1)

def downlink(fromsock, tosock):
    print "downlink started!"
    while True:
        data = tosock.recv(1024*64)
        fromsock.send(data)

def uplink(fromsock, tosock):
    print "uplink started!"
    while True:
        data = fromsock.recv(1024*64)
        tosock.send(data)

while True:
    print "waiting for local connection.."
    fromsock,addr = fromlisten.accept()
    tosock.connect(REMOTE_SERVER_ADDRESS)
    tosock.send("16030100dd010000d90303524408300450b48f90ead85d002384a64b6c1dc570ffd1e0aca36728f3a3fff7000042c030c02cc028c024c014c00ac032c02ec02ac026c00fc005009d003d00350084c02fc02bc027c023c013c009c031c02dc029c025c00ec004009c003c002f004100ff0100006e00000015001300001070672e63646e2e76696265722e636f6d000b000403000102000a001c001a00170019001c001b0018001a0016000e000d000b000c0009000a00230000000d0020001e060106020603050105020503040104020403030103020303020102020203000f000101".decode("hex"))
    print "endpoints connected!"
    t1 = threading.Thread(target=uplink, args=(fromsock, tosock,))
    t2 = threading.Thread(target=downlink, args=(fromsock, tosock,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
RemoteForwardingServer.py (single connection manual restart)
Code:
#!/usr/bin/python

import socket
import time
import threading

# Binding address ng RemoteForwardingServer
FAKESSL_SERVER_ADDRESS = ('XXX.XXX.XXX.XXX', 443)

# Address ng OpenVPN Server relative sa RemoteForwardingServer
VPN_SERVER_ADDRESS = ("localhost", 1194)

tosock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
fromlisten = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
fromlisten.bind(FAKESSL_SERVER_ADDRESS)
fromlisten.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
fromlisten.listen(1)

def downlink(fromsock, tosock):
    print fromsock
    print tosock
    print "downlink started!"
    while True:
        data = tosock.recv(1024*64)
        fromsock.send(data)

def uplink(fromsock, tosock):
    print fromsock
    print tosock
    print "uplink started!"
    print "discarding hello!"
    fromsock.recv(1024*64)

    while True:
        data = fromsock.recv(1024*64)
        tosock.send(data)

while True:
    print "waiting for local connection.."
    fromsock,addr = fromlisten.accept()
    tosock.connect(VPN_SERVER_ADDRESS)
    print "endpoints connected!"
    t1 = threading.Thread(target=uplink, args=(fromsock, tosock,))
    t2 = threading.Thread(target=downlink, args=(fromsock, tosock,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
RemoteForwardingServer.cpp (multiple connection, c++17)
C++:
#include <iostream>
#include <exception>
#include <cstring>
#include <cstdlib>
#include <string>
#include <sstream>
#include <thread>
#include <chrono>
#include <sys/socket.h>
#include <netinet/in.h>
#include <error.h>
#include <signal.h>

const std::string s;
uint64_t timeBase;

template<typename... Ts>
void Log(Ts&&... ts)
{
    uint64_t timeNow = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
    std::stringstream ss;
    ss << ((timeNow-timeBase)/1000.0) << " ";
    (ss << ... << std::forward<Ts>(ts));
    std::cout << ss.str() << "\n";
}

class Forwarder
{
public:
    Forwarder() = delete;
    Forwarder(int pClientFd)
        : mClientFd(pClientFd)
    {}

    void run()
    {
        constexpr size_t buffersz = 1024*64;
        char buffer[buffersz];

        Log("Waiting for fake hello.");
        int rc = recv(mClientFd, buffer, buffersz, 0);

        if (rc<=0)
        {
            Log("Fake Init Message Receive Error! error=", strerror(errno));
            return;
        }

        Log("Fake Init Message  Receive size=", rc);

        mTargetFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        sockaddr_in targetaddr;
        targetaddr.sin_family = AF_INET;
        targetaddr.sin_addr.s_addr = ntohl(0x7f000001); // localhost
        targetaddr.sin_port = ntohs(1194); // port

        Log("Connecting to target host ",
            (targetaddr.sin_addr.s_addr)&0xFF, ".",
            (targetaddr.sin_addr.s_addr>>8)&0xFF, ".",
            (targetaddr.sin_addr.s_addr>>16)&0xFF, ".",
            (targetaddr.sin_addr.s_addr>>24)&0xFF, ":",
            htons(targetaddr.sin_port));

        if (connect(mTargetFd, (struct sockaddr *)&targetaddr , sizeof(targetaddr)) < 0)
        {
            Log("Connect to target host failed! error=",  strerror(errno));
            return;
        }

        std::thread tdl(&Forwarder::downlink, this);
        std::thread tul(&Forwarder::uplink, this);
        tdl.join();
        tul.join();
        Log("Client ended!");
    }
private:

    void uplink()
    {
        Log("Uplink started!");
        constexpr size_t buffersz = 1024*64;
        char buffer[buffersz];
        while (1)
        {
            int rc = recv(mClientFd, buffer, buffersz, 0);
            if (rc<=0)
            {
                Log("Uplink receive failed!", rc, " error=",  strerror(errno));
                return;
            }
            //Log("Uplink data size:", rc);
            rc = send(mTargetFd, buffer, rc, 0);
            if (rc<=0)
            {
                Log("Uplink send failed!", rc, " error=",  strerror(errno));
                return;
            }
        }
    }
    void downlink()
    {
        Log("Downlink started!");
        constexpr size_t buffersz = 1024*64;
        char buffer[buffersz];
        while (1)
        {
            int rc = recv(mTargetFd, buffer, buffersz, 0);
            if (rc<=0)
            {
                Log("Downlink receive failed!", rc, " error=",  strerror(errno));
                return;
            }
            //Log("Downlink data size=", rc);
            rc = send(mClientFd, buffer, rc, 0);
            if (rc<=0)
            {
                Log("Downlink send failed!", rc, " error=",  strerror(errno));
                return;
            }
        }
    }

    template<typename... Ts>
    void Log(Ts&&... ts)
    {
        ::Log("Forwarder[", mClientFd,"]: ", std::forward<Ts>(ts)...);
    }

    int mClientFd;
    int mTargetFd = -1;
};

int main(int argc, const char* argv[])
{
    signal(SIGPIPE, SIG_IGN);

    timeBase = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
    const unsigned int port = atoi(argv[1]);
    int serverfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    int addreuse = 1;
    setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &addreuse, sizeof(addreuse));

    sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(port);

    if (bind(serverfd, (sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    {
        throw std::runtime_error(s + "bind: " + strerror(errno));
    }

    Log("Bound to port:", port);

    if (listen(serverfd, 5)<0)
    {
        throw std::runtime_error(s + "listen: " + strerror(errno));
    }

    Log("listening...");

    while (true)
    {
        sockaddr_in clientaddr;
        socklen_t clientaddrsz = sizeof(clientaddr);
        Log("Waiting for connection...");
        int clientfd = accept(serverfd, (sockaddr*)&clientaddr, &clientaddrsz);
        std::stringstream ss;
        Log("Client connected! id:", clientfd, " address:",
            (clientaddr.sin_addr.s_addr)&0xFF, ".",
            (clientaddr.sin_addr.s_addr>>8)&0xFF, ".",
            (clientaddr.sin_addr.s_addr>>16)&0xFF, ".",
            (clientaddr.sin_addr.s_addr>>24)&0xFF, ":",
            htons(clientaddr.sin_port));
        std::cout << ss.str();
        std::thread([clientfd]()
        {
            return Forwarder(clientfd).run();
        }).detach();
    }
}
3. DNS
May nakita ako dito sa forums na DNS Tunneling gamit nya.
Sino nang nakapag setup ng DNS Tunneling server?
Though may disadvantage yung DNS kung UDP gamit, kasi limited lang yung packet size to 512 bytes (plus headers pa yun). Theoretically pweding TCP yung DNS query mo di ko lang sure kung naka blocked ba yun sa ISP.

Additional Info for TCP:
Nag try ako gumawa ng echo tcp server using port 53 naka host sa lightsail, gumagana cya pero sobrang bagal. Yung tinry ko di ko na niwrap sa DNS data packet. So after tcp yung data na talaga mismo. Limited lang din yung connection time ~3 seconds lang or less pagkatapos nun mag TCP RESET na. Parang may side effect siya ngayon, di ko sure kung nagkataon lang pa pero sa area ko dito never pa akong nagka ganito, parang naga throttle ngayon yung traffic ko to a point na unsuable na cya baka kelangan ko nang mag palit ng sim. Na detect ata ng isp yung traffic sa 53 na hindi legit DNS query.

Additional Info for UDP:
Throttled din sa UDP yung ~10 packets per second lang dun sa test ko, 2 packet burst every 200ms. Malabong gamitin to for tunneling (5kbps lang!!!), siguro pwedi to sa mga maliliit lang talaga na data, maybe IoT?

4. ICMP
Nakita ko din to sa forums.
Mas malaki throughput neto dapat compared sa DNS over UDP, yung payload nito 65k.
Sino nang nakapag setup ng ICMP Tunneling server?
Currently di ko pa magagawa yung testing neto kasi yung ICMP packet always blocked siya sa lightsail for security reason. Nagpaplan palang ako bumili ng droplets kaso mahal kasi yung initial na credits.

Goal natin mga ka PHC is gumawa ng all in one solution in one package isang app lang pwedi na sa lahat. Kung sino gusto mag collaborate PM me.
 

Edmar Hub

Eternal Poster
prinzrainer nice quality content working yung Method 1 TS same din concept ng Stunnel, pero may konting problema lang tayo.

  • Whenever i reconnected i need to run again the local forwarding script & the server forwarding script
  • Local ports are not killed during disconnection

And by the way, how about 2 users connecting on the same port FAKESSL_SERVER_ADDRESS at the same time?

Please PM me anytime for Testing :)

601901
 

prinzrainer

Journeyman
, Last edited:
Edmar Hub pang POC lang talaga yan kung gusto mo multiple connection sa server side dapat may accept loop ka then every new connection, new forwarding thread yun.

Parang ganito:
C++:
#include <iostream>
#include <exception>
#include <cstring>
#include <cstdlib>
#include <string>
#include <sstream>
#include <thread>
#include <chrono>
#include <sys/socket.h>
#include <netinet/in.h>
#include <error.h>
#include <signal.h>

const std::string s;
uint64_t timeBase;

template<typename... Ts>
void Log(Ts&&... ts)
{
    uint64_t timeNow = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
    std::stringstream ss;
    ss << ((timeNow-timeBase)/1000.0) << " ";
    (ss << ... << std::forward<Ts>(ts));
    std::cout << ss.str() << "\n";
}

class Forwarder
{
public:
    Forwarder() = delete;
    Forwarder(int pClientFd)
        : mClientFd(pClientFd)
    {}

    void run()
    {
        constexpr size_t buffersz = 1024*64;
        char buffer[buffersz];

        Log("Waiting for fake hello.");
        int rc = recv(mClientFd, buffer, buffersz, 0);

        if (rc<=0)
        {
            Log("Fake Init Message Receive Error! error=", strerror(errno));
            return;
        }

        Log("Fake Init Message  Receive size=", rc);

        mTargetFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        sockaddr_in targetaddr;
        targetaddr.sin_family = AF_INET;
        targetaddr.sin_addr.s_addr = ntohl(0x7f000001); // localhost
        targetaddr.sin_port = ntohs(1194); // port

        Log("Connecting to target host ",
            (targetaddr.sin_addr.s_addr)&0xFF, ".",
            (targetaddr.sin_addr.s_addr>>8)&0xFF, ".",
            (targetaddr.sin_addr.s_addr>>16)&0xFF, ".",
            (targetaddr.sin_addr.s_addr>>24)&0xFF, ":",
            htons(targetaddr.sin_port));

        if (connect(mTargetFd, (struct sockaddr *)&targetaddr , sizeof(targetaddr)) < 0)
        {
            Log("Connect to target host failed! error=",  strerror(errno));
            return;
        }

        std::thread tdl(&Forwarder::downlink, this);
        std::thread tul(&Forwarder::uplink, this);
        tdl.join();
        tul.join();
        Log("Client ended!");
    }
private:

    void uplink()
    {
        Log("Uplink started!");
        constexpr size_t buffersz = 1024*64;
        char buffer[buffersz];
        while (1)
        {
            int rc = recv(mClientFd, buffer, buffersz, 0);
            if (rc<=0)
            {
                Log("Uplink receive failed!", rc, " error=",  strerror(errno));
                return;
            }
            //Log("Uplink data size:", rc);
            rc = send(mTargetFd, buffer, rc, 0);
            if (rc<=0)
            {
                Log("Uplink send failed!", rc, " error=",  strerror(errno));
                return;
            }
        }
    }
    void downlink()
    {
        Log("Downlink started!");
        constexpr size_t buffersz = 1024*64;
        char buffer[buffersz];
        while (1)
        {
            int rc = recv(mTargetFd, buffer, buffersz, 0);
            if (rc<=0)
            {
                Log("Downlink receive failed!", rc, " error=",  strerror(errno));
                return;
            }
            //Log("Downlink data size=", rc);
            rc = send(mClientFd, buffer, rc, 0);
            if (rc<=0)
            {
                Log("Downlink send failed!", rc, " error=",  strerror(errno));
                return;
            }
        }
    }

    template<typename... Ts>
    void Log(Ts&&... ts)
    {
        ::Log("Forwarder[", mClientFd,"]: ", std::forward<Ts>(ts)...);
    }

    int mClientFd;
    int mTargetFd = -1;
};

int main(int argc, const char* argv[])
{
    signal(SIGPIPE, SIG_IGN);

    timeBase = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
    const unsigned int port = atoi(argv[1]);
    int serverfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    int addreuse = 1;
    setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &addreuse, sizeof(addreuse));

    sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(port);

    if (bind(serverfd, (sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    {
        throw std::runtime_error(s + "bind: " + strerror(errno));
    }

    Log("Bound to port:", port);

    if (listen(serverfd, 5)<0)
    {
        throw std::runtime_error(s + "listen: " + strerror(errno));
    }

    Log("listening...");

    while (true)
    {
        sockaddr_in clientaddr;
        socklen_t clientaddrsz = sizeof(clientaddr);
        Log("Waiting for connection...");
        int clientfd = accept(serverfd, (sockaddr*)&clientaddr, &clientaddrsz);
        std::stringstream ss;
        Log("Client connected! id:", clientfd, " address:",
            (clientaddr.sin_addr.s_addr)&0xFF, ".",
            (clientaddr.sin_addr.s_addr>>8)&0xFF, ".",
            (clientaddr.sin_addr.s_addr>>16)&0xFF, ".",
            (clientaddr.sin_addr.s_addr>>24)&0xFF, ":",
            htons(clientaddr.sin_port));
        std::cout << ss.str();
        std::thread([clientfd]()
        {
            return Forwarder(clientfd).run();
        }).detach();
    }
}
Compile mo lang for c++17
g++ -std=c++17 RemoteForwardingServer.cpp -lpthread -o RemoteForwardingServer

Then run under nohup para background yung process (kahit ma close yung ssh session)
Tatangapin neto kung anong port mag listen yung RemoteForwardingServer
nohup ./RemoteForwardingServer 8080

Handled na dito yung multiple connections palitan mo nalang yung targetaddr kung ano yung naka set sa OpenVPN mo (or ibang remote OpenVPN server). Kung gusto mo dynamic yung target address, pwedi mong i parse yung HTTP REQUEST then dun mo kunin yung information for targetaddr.
 

Edmar Hub

Eternal Poster
Edmar Hub pang POC lang talaga yan kung gusto mo multiple connection sa server side dapat may accept loop ka then every new connection, new forwarding thread yun.

Parang ganito:
C++:
#include <iostream>
#include <exception>
#include <cstring>
#include <cstdlib>
#include <string>
#include <sstream>
#include <thread>
#include <chrono>
#include <sys/socket.h>
#include <netinet/in.h>
#include <error.h>
#include <signal.h>

const std::string s;
uint64_t timeBase;

template<typename... Ts>
void Log(Ts&&... ts)
{
    uint64_t timeNow = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
    std::stringstream ss;
    ss << ((timeNow-timeBase)/1000.0) << " ";
    (ss << ... << std::forward<Ts>(ts));
    std::cout << ss.str() << "\n";
}

class Forwarder
{
public:
    Forwarder() = delete;
    Forwarder(int pClientFd)
        : mClientFd(pClientFd)
    {}

    void run()
    {
        constexpr size_t buffersz = 1024*64;
        char buffer[buffersz];

        Log("Waiting for fake hello.");
        int rc = recv(mClientFd, buffer, buffersz, 0);

        if (rc<=0)
        {
            Log("Fake Init Message Receive Error! error=", strerror(errno));
            return;
        }

        Log("Fake Init Message  Receive size=", rc);

        mTargetFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        sockaddr_in targetaddr;
        targetaddr.sin_family = AF_INET;
        targetaddr.sin_addr.s_addr = ntohl(0x7f000001); // localhost
        targetaddr.sin_port = ntohs(1194); // port

        Log("Connecting to target host ",
            (targetaddr.sin_addr.s_addr)&0xFF, ".",
            (targetaddr.sin_addr.s_addr>>8)&0xFF, ".",
            (targetaddr.sin_addr.s_addr>>16)&0xFF, ".",
            (targetaddr.sin_addr.s_addr>>24)&0xFF, ":",
            htons(targetaddr.sin_port));

        if (connect(mTargetFd, (struct sockaddr *)&targetaddr , sizeof(targetaddr)) < 0)
        {
            Log("Connect to target host failed! error=",  strerror(errno));
            return;
        }

        std::thread tdl(&Forwarder::downlink, this);
        std::thread tul(&Forwarder::uplink, this);
        tdl.join();
        tul.join();
        Log("Client ended!");
    }
private:

    void uplink()
    {
        Log("Uplink started!");
        constexpr size_t buffersz = 1024*64;
        char buffer[buffersz];
        while (1)
        {
            int rc = recv(mClientFd, buffer, buffersz, 0);
            if (rc<=0)
            {
                Log("Uplink receive failed!", rc, " error=",  strerror(errno));
                return;
            }
            //Log("Uplink data size:", rc);
            rc = send(mTargetFd, buffer, rc, 0);
            if (rc<=0)
            {
                Log("Uplink send failed!", rc, " error=",  strerror(errno));
                return;
            }
        }
    }
    void downlink()
    {
        Log("Downlink started!");
        constexpr size_t buffersz = 1024*64;
        char buffer[buffersz];
        while (1)
        {
            int rc = recv(mTargetFd, buffer, buffersz, 0);
            if (rc<=0)
            {
                Log("Downlink receive failed!", rc, " error=",  strerror(errno));
                return;
            }
            //Log("Downlink data size=", rc);
            rc = send(mClientFd, buffer, rc, 0);
            if (rc<=0)
            {
                Log("Downlink send failed!", rc, " error=",  strerror(errno));
                return;
            }
        }
    }

    template<typename... Ts>
    void Log(Ts&&... ts)
    {
        ::Log("Forwarder[", mClientFd,"]: ", std::forward<Ts>(ts)...);
    }

    int mClientFd;
    int mTargetFd = -1;
};

int main(int argc, const char* argv[])
{
    signal(SIGPIPE, SIG_IGN);

    timeBase = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count();
    const unsigned int port = atoi(argv[1]);
    int serverfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    int addreuse = 1;
    setsockopt(serverfd, SOL_SOCKET, SO_REUSEADDR, &addreuse, sizeof(addreuse));

    sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port = htons(port);

    if (bind(serverfd, (sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    {
        throw std::runtime_error(s + "bind: " + strerror(errno));
    }

    Log("Bound to port:", port);

    if (listen(serverfd, 5)<0)
    {
        throw std::runtime_error(s + "listen: " + strerror(errno));
    }

    Log("listening...");

    while (true)
    {
        sockaddr_in clientaddr;
        socklen_t clientaddrsz = sizeof(clientaddr);
        Log("Waiting for connection...");
        int clientfd = accept(serverfd, (sockaddr*)&clientaddr, &clientaddrsz);
        std::stringstream ss;
        Log("Client connected! id:", clientfd, " address:",
            (clientaddr.sin_addr.s_addr)&0xFF, ".",
            (clientaddr.sin_addr.s_addr>>8)&0xFF, ".",
            (clientaddr.sin_addr.s_addr>>16)&0xFF, ".",
            (clientaddr.sin_addr.s_addr>>24)&0xFF, ":",
            htons(clientaddr.sin_port));
        std::cout << ss.str();
        std::thread([clientfd]()
        {
            return Forwarder(clientfd).run();
        }).detach();
    }
}
Compile mo lang for c++17
g++ -std=c++17 RemoteForwardingServer.cpp -lpthread -o RemoteForwardingServer

Then run under nohup para background yung process (kahit ma close yung ssh session)
Tatangapin neto kung anong port mag listen yung RemoteForwardingServer
nohup ./RemoteForwardingServer 8080

Handled na dito yung multiple connections palitan mo nalang yung targetaddr kung ano yung naka set sa OpenVPN mo (or ibang remote OpenVPN server). Kung gusto mo dynamic yung target address, pwedi mong i parse yung HTTP REQUEST then dun mo kunin yung information for targetaddr.
alright thanks got the idea :)
 

Trending On This Forum

Unanswered Topics

Top