mirror of
https://codeberg.org/scip/udpxd.git
synced 2025-12-16 19:40:58 +01:00
changed -d to -t; -d is now for daemonizing, removed -f; drop privileges if run as root and in daemon mode and chroot
This commit is contained in:
@@ -10,8 +10,8 @@ compiler:
|
|||||||
script:
|
script:
|
||||||
- make
|
- make
|
||||||
- sudo make install
|
- sudo make install
|
||||||
- sudo udpxd -l 127.0.0.1:53 -d 8.8.8.8:53
|
- sudo udpxd -l 127.0.0.1:53 -d 8.8.8.8:53 -d
|
||||||
- sudo udpxd -l [::1]:53 -d [2001:4860:4860::8888]:53
|
- sudo udpxd -l [::1]:53 -t [2001:4860:4860::8888]:53 -d
|
||||||
- dig +nocmd +noall +answer google.de a @127.0.0.1
|
- dig +nocmd +noall +answer google.de a @127.0.0.1
|
||||||
- dig +nocmd +noall +answer google.de a @::1
|
- dig +nocmd +noall +answer google.de a @::1
|
||||||
- sudo killall udpxd
|
- sudo killall udpxd
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ install:
|
|||||||
|
|
||||||
build_script:
|
build_script:
|
||||||
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; make"'
|
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; make"'
|
||||||
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; cygstart --hide ./udpxd -l 127.0.0.1:53 -d 8.8.8.8:53 -f"'
|
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; cygstart --hide ./udpxd -l 127.0.0.1:53 -t 8.8.8.8:53"'
|
||||||
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; cygstart --hide ./udpxd -l [::1]:53 -d 8.8.8.8:53 -f"'
|
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; cygstart --hide ./udpxd -l [::1]:53 -t 8.8.8.8:53"'
|
||||||
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; dig www.google.de soa @127.0.0.1"'
|
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; dig www.google.de soa @127.0.0.1"'
|
||||||
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; dig www.google.de soa @::1"'
|
- '%CYG_BASH% -lc "cd $APPVEYOR_BUILD_FOLDER; exec 0</dev/null; dig www.google.de soa @::1"'
|
||||||
|
|
||||||
|
|||||||
102
net.c
102
net.c
@@ -81,9 +81,14 @@ int bindsocket( host_t *sock_h) {
|
|||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int start_listener (char *inip, char *inpt, char *srcip, char *dstip, char *dstpt, char *pidfile) {
|
/*
|
||||||
host_t *listen_h, *dst_h, *bind_h;
|
returns:
|
||||||
|
-1: error in any case
|
||||||
|
0: parent not forked (fork disabled)
|
||||||
|
1: parent after successful fork
|
||||||
|
2: child after successful fork
|
||||||
|
*/
|
||||||
|
int daemonize(char *pidfile) {
|
||||||
if(FORKED) {
|
if(FORKED) {
|
||||||
// fork
|
// fork
|
||||||
pid_t pid, sid;
|
pid_t pid, sid;
|
||||||
@@ -100,15 +105,16 @@ int start_listener (char *inip, char *inpt, char *srcip, char *dstip, char *dstp
|
|||||||
/* leave parent */
|
/* leave parent */
|
||||||
if((fd = fopen(pidfile, "w")) == NULL) {
|
if((fd = fopen(pidfile, "w")) == NULL) {
|
||||||
perror("failed to write pidfile");
|
perror("failed to write pidfile");
|
||||||
return 1;
|
return -1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(fd, "%d\n", pid);
|
fprintf(fd, "%d\n", pid);
|
||||||
fclose(fd);
|
fclose(fd);
|
||||||
}
|
}
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* child */
|
||||||
|
|
||||||
sid = setsid();
|
sid = setsid();
|
||||||
if (sid < 0) {
|
if (sid < 0) {
|
||||||
@@ -116,17 +122,82 @@ int start_listener (char *inip, char *inpt, char *srcip, char *dstip, char *dstp
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
umask(0);
|
||||||
|
|
||||||
|
openlog("udpxd", LOG_NOWAIT|LOG_PID, LOG_USER);
|
||||||
|
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drop_privileges(char *user, char *chrootdir) {
|
||||||
|
struct passwd *pw = getpwnam(user);
|
||||||
|
uid_t me = getuid();
|
||||||
|
|
||||||
if ((chdir("/")) < 0) {
|
if ((chdir("/")) < 0) {
|
||||||
perror("failed to chdir to /");
|
perror("failed to chdir to /");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
umask(0);
|
if(me == 0) {
|
||||||
close(STDIN_FILENO);
|
/* drop privileges */
|
||||||
close(STDOUT_FILENO);
|
if(chroot(chrootdir) != 0) {
|
||||||
close(STDERR_FILENO);
|
perror("failed to chroot");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
openlog("udpxd", LOG_NOWAIT|LOG_PID, LOG_USER);
|
if(pw == NULL) {
|
||||||
|
perror("user not found");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(setegid(pw->pw_gid) != 0) {
|
||||||
|
perror("could not set egid");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(setgid(pw->pw_gid) != 0) {
|
||||||
|
perror("could not set gid");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(setuid(pw->pw_uid) != 0) {
|
||||||
|
perror("could not set uid");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(seteuid(pw->pw_uid) != 0) {
|
||||||
|
perror("could not set euid");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setuid(0) != -1) {
|
||||||
|
fprintf(stderr, "error, managed to regain root privileges after dropping them!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int start_listener (char *inip, char *inpt, char *srcip, char *dstip,
|
||||||
|
char *dstpt, char *pidfile, char *chrootdir, char *user) {
|
||||||
|
host_t *listen_h, *dst_h, *bind_h;
|
||||||
|
|
||||||
|
int dm = daemonize(pidfile);
|
||||||
|
switch(dm) {
|
||||||
|
case -1:
|
||||||
|
return 1; /* parent, fork error */
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
break; /* parent, not forking */
|
||||||
|
case 1:
|
||||||
|
return 0; /* parent, fork ok, leave */
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
break; /* child, fork ok, continue */
|
||||||
}
|
}
|
||||||
|
|
||||||
listen_h = get_host(inip, atoi(inpt), NULL, NULL);
|
listen_h = get_host(inip, atoi(inpt), NULL, NULL);
|
||||||
@@ -157,6 +228,17 @@ int start_listener (char *inip, char *inpt, char *srcip, char *dstip, char *dstp
|
|||||||
verbose("\n");
|
verbose("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(drop_privileges(user, chrootdir) != 0) {
|
||||||
|
host_clean(bind_h);
|
||||||
|
host_clean(listen_h);
|
||||||
|
host_clean(dst_h);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(STDIN_FILENO);
|
||||||
|
close(STDOUT_FILENO);
|
||||||
|
close(STDERR_FILENO);
|
||||||
|
|
||||||
main_loop(listen, listen_h, bind_h, dst_h);
|
main_loop(listen, listen_h, bind_h, dst_h);
|
||||||
|
|
||||||
host_clean(bind_h);
|
host_clean(bind_h);
|
||||||
|
|||||||
6
net.h
6
net.h
@@ -38,6 +38,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
@@ -54,7 +55,10 @@ void handle_inside(int inside, host_t *listen_h, host_t *bind_h, host_t *dst_h);
|
|||||||
void handle_outside(int inside, int outside, host_t *outside_h);
|
void handle_outside(int inside, int outside, host_t *outside_h);
|
||||||
|
|
||||||
int main_loop(int listensocket, host_t *listen_h, host_t *bind_h, host_t *dst_h);
|
int main_loop(int listensocket, host_t *listen_h, host_t *bind_h, host_t *dst_h);
|
||||||
int start_listener (char *inip, char *inpt, char *srcip, char *dstip, char *dstpt, char *pidfile);
|
int start_listener (char *inip, char *inpt, char *srcip, char *dstip,
|
||||||
|
char *dstpt, char *pidfile, char *chrootdir, char *user);
|
||||||
|
int daemonize(char *pidfile);
|
||||||
|
int drop_privileges(char *user, char *chrootdir);
|
||||||
|
|
||||||
int fill_set(fd_set *fds);
|
int fill_set(fd_set *fds);
|
||||||
int get_sender(fd_set *fds);
|
int get_sender(fd_set *fds);
|
||||||
|
|||||||
43
udpxd.1
43
udpxd.1
@@ -124,7 +124,7 @@
|
|||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
.\"
|
.\"
|
||||||
.IX Title "UDPXD 1"
|
.IX Title "UDPXD 1"
|
||||||
.TH UDPXD 1 "2015-04-26" "perl v5.14.2" "User Contributed Perl Documentation"
|
.TH UDPXD 1 "2015-04-27" "perl v5.14.2" "User Contributed Perl Documentation"
|
||||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||||
.\" way too many mistakes in technical documents.
|
.\" way too many mistakes in technical documents.
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
@@ -139,12 +139,14 @@ udpxd \- A general purpose UDP relay/port forwarder/proxy
|
|||||||
\& Options:
|
\& Options:
|
||||||
\& \-\-listen \-l <ip:port> listen for incoming requests
|
\& \-\-listen \-l <ip:port> listen for incoming requests
|
||||||
\& \-\-bind \-b <ip> bind ip used for outgoing requests
|
\& \-\-bind \-b <ip> bind ip used for outgoing requests
|
||||||
\& \-\-dest \-d <ip:port> destination to forward requests to
|
\& \-\-to \-t <ip:port> destination to forward requests to
|
||||||
\& \-\-foreground \-f don\*(Aqt fork into background
|
\& \-\-daemon \-d daemon mode, fork into background
|
||||||
\& \-\-pidfile \-p <file> pidfile, default: /var/run/udpxd.pid
|
\& \-\-pidfile \-p <file> pidfile, default: /var/run/udpxd.pid
|
||||||
|
\& \-\-user \-u <user> run as user (only in daemon mode)
|
||||||
|
\& \-\-chroot \-c <path> chroot to <path> (only in daemon mode)
|
||||||
\& \-\-help \-h \-? print help message
|
\& \-\-help \-h \-? print help message
|
||||||
\& \-\-version \-v print program version
|
\& \-\-version \-V print program version
|
||||||
\& \-\-verbose \-V enable verbose logging
|
\& \-\-verbose \-v enable verbose logging
|
||||||
.Ve
|
.Ve
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
.IX Header "DESCRIPTION"
|
.IX Header "DESCRIPTION"
|
||||||
@@ -155,7 +157,7 @@ for outgoing packets.
|
|||||||
.PP
|
.PP
|
||||||
It listens on the ip address and port specified with \fB\-l\fR
|
It listens on the ip address and port specified with \fB\-l\fR
|
||||||
and waits for incoming udp packets. If one arrives, it sends
|
and waits for incoming udp packets. If one arrives, it sends
|
||||||
it to the destination specified with \fB\-d\fR. Responses will
|
it to the destination specified with \fB\-t\fR. Responses will
|
||||||
be sent back accordingly.
|
be sent back accordingly.
|
||||||
.PP
|
.PP
|
||||||
If \fB\-b\fR has not been specified, udpxd uses the operating
|
If \fB\-b\fR has not been specified, udpxd uses the operating
|
||||||
@@ -165,23 +167,25 @@ binds to the given ip address and uses this as the source
|
|||||||
address.
|
address.
|
||||||
.PP
|
.PP
|
||||||
In any case, udpxd behaves like a proxy. The receiving end
|
In any case, udpxd behaves like a proxy. The receiving end
|
||||||
(\fB\-d\fR) only sees the source ip address of the outgoing
|
(\fB\-t\fR) only sees the source ip address of the outgoing
|
||||||
interface of the system running udpxd or the address specified
|
interface of the system running udpxd or the address specified
|
||||||
with \fB\-b\fR.
|
with \fB\-b\fR.
|
||||||
.PP
|
.PP
|
||||||
The options \fB\-l\fR and \fB\-d\fR are mandatory.
|
The options \fB\-l\fR and \fB\-t\fR are mandatory.
|
||||||
.PP
|
.PP
|
||||||
If the option \fB\-f\fR has not been specified, udpxd forks into
|
If the option \fB\-d\fR has been specified, udpxd forks into
|
||||||
the background and becomes a daemon. It writes it pidfile to
|
the background and becomes a daemon. It writes it pidfile to
|
||||||
\&\f(CW\*(C`/var/run/udpxd.pid\*(C'\fR, which can be changed with the \fB\-p\fR
|
\&\f(CW\*(C`/var/run/udpxd.pid\*(C'\fR, which can be changed with the \fB\-p\fR
|
||||||
option.
|
option. If started as root, it also drops privileges to the
|
||||||
|
user \f(CW\*(C`nobody\*(C'\fR or the user specified with \fB\-u\fR and chroots
|
||||||
|
to \f(CW\*(C`/var/empty\*(C'\fR or the directory specified with \fB\-c\fR.
|
||||||
.PP
|
.PP
|
||||||
\&\fBCaution: udpxd does not drop its privileges. If started as
|
\&\fBCaution: if not running in daemon mode, udpxd does not drop
|
||||||
root, it will continue to run as root. This may change in the
|
its privileges and will continue to run as root (if started as
|
||||||
future.\fR
|
root).\fR
|
||||||
.PP
|
.PP
|
||||||
Udpxd supports ip version 4 and 6, it doesn't support hostnames,
|
Udpxd supports ip version 4 and 6, it doesn't support hostnames,
|
||||||
\&\-l, \-d and \-b must be ip addresses. In order to specify an ipv6
|
\&\fB\-l\fR, \fB\-t\fR and \fB\-b\fR must be ip addresses. In order to specify an ipv6
|
||||||
address and a port, use:
|
address and a port, use:
|
||||||
.PP
|
.PP
|
||||||
.Vb 1
|
.Vb 1
|
||||||
@@ -216,7 +220,7 @@ an ntp server in network 192.168.1.0/24; and you dont operate a
|
|||||||
firewall, nat or routing on 'foo'. Run udpxd like this:
|
firewall, nat or routing on 'foo'. Run udpxd like this:
|
||||||
.PP
|
.PP
|
||||||
.Vb 1
|
.Vb 1
|
||||||
\& udpxd \-l 10.0.0.1:123 \-d 192.168.1.199:123
|
\& udpxd \-l 10.0.0.1:123 \-t 192.168.1.199:123
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
Now, if a client with the source ip address 10.0.0.110 sends
|
Now, if a client with the source ip address 10.0.0.110 sends
|
||||||
@@ -244,7 +248,7 @@ In order to use 192.168.1.45 as the source ip address, use the
|
|||||||
\&\fB\-b\fR parameter:
|
\&\fB\-b\fR parameter:
|
||||||
.PP
|
.PP
|
||||||
.Vb 1
|
.Vb 1
|
||||||
\& udpxd \-l 10.0.0.1:123 \-d 192.168.1.199:123 \-b 192.168.1.45
|
\& udpxd \-l 10.0.0.1:123 \-t 192.168.1.199:123 \-b 192.168.1.45
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
In this case for the client everything looks as before, but the
|
In this case for the client everything looks as before, but the
|
||||||
@@ -255,19 +259,18 @@ Here we listen on the ip v6 loopback address and forward traffic
|
|||||||
to another ip v6 destination address:
|
to another ip v6 destination address:
|
||||||
.PP
|
.PP
|
||||||
.Vb 1
|
.Vb 1
|
||||||
\& udpxd \-l [::1]:53 \-d [2001:4860:4860::8888]:53
|
\& udpxd \-l [::1]:53 \-t [2001:4860:4860::8888]:53
|
||||||
.Ve
|
.Ve
|
||||||
.PP
|
.PP
|
||||||
Or, we could listen on an ip v4 address and forward to an ip v6
|
Or, we could listen on an ip v4 address and forward to an ip v6
|
||||||
address:
|
address:
|
||||||
.PP
|
.PP
|
||||||
.Vb 1
|
.Vb 1
|
||||||
\& udpxd \-l 192.168.1.1:53 \-d [2001:4860:4860::8888]:53
|
\& udpxd \-l 192.168.1.1:53 \-t [2001:4860:4860::8888]:53
|
||||||
.Ve
|
.Ve
|
||||||
.SH "FILES"
|
.SH "FILES"
|
||||||
.IX Header "FILES"
|
.IX Header "FILES"
|
||||||
\&\fB/var/run/udpxd.pid\fR: created if running in daemon mode (\-f not
|
\&\fB/var/run/udpxd.pid\fR: created if running in daemon mode (\fB\-d\fR).
|
||||||
specified).
|
|
||||||
.SH "BUGS"
|
.SH "BUGS"
|
||||||
.IX Header "BUGS"
|
.IX Header "BUGS"
|
||||||
In order to report a bug, unexpected behavior, feature requests
|
In order to report a bug, unexpected behavior, feature requests
|
||||||
|
|||||||
79
udpxd.c
79
udpxd.c
@@ -26,7 +26,7 @@
|
|||||||
/* global client list */
|
/* global client list */
|
||||||
client_t *clients = NULL;
|
client_t *clients = NULL;
|
||||||
int VERBOSE = 0;
|
int VERBOSE = 0;
|
||||||
int FORKED = 1;
|
int FORKED = 0;
|
||||||
|
|
||||||
/* parse ip:port */
|
/* parse ip:port */
|
||||||
int parse_ip(char *src, char *ip, char *pt) {
|
int parse_ip(char *src, char *ip, char *pt) {
|
||||||
@@ -87,23 +87,47 @@ int parse_ip(char *src, char *ip, char *pt) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void usage() {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Usage: udpxd [-lbdfpvhV]\n\n"
|
||||||
|
"Options:\n"
|
||||||
|
"--listen -l <ip:port> listen for incoming requests\n"
|
||||||
|
"--bind -b <ip> bind ip used for outgoing requests\n"
|
||||||
|
"--to -t <ip:port> destination to forward requests to\n"
|
||||||
|
"--daemon -d daemon mode, fork into background\n"
|
||||||
|
"--pidfile -p <file> pidfile, default: /var/run/udpxd.pid\n"
|
||||||
|
"--user -u <user> run as user (only in daemon mode)\n"
|
||||||
|
"--chroot -c <path> chroot to <path> (only in daemon mode)\n"
|
||||||
|
"--help -h -? print help message\n"
|
||||||
|
"--version -V print program version\n"
|
||||||
|
"--verbose -v enable verbose logging\n\n"
|
||||||
|
"Options -l and -t are mandatory.\n\n"
|
||||||
|
"This is udpxd version %s.\n", UDPXD_VERSION
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main ( int argc, char* argv[] ) {
|
int main ( int argc, char* argv[] ) {
|
||||||
int opt, err;
|
int opt, err;
|
||||||
char *inip, *inpt, *srcip, *dstip, *dstpt;
|
char *inip, *inpt, *srcip, *dstip, *dstpt;
|
||||||
char pidfile[MAX_BUFFER_SIZE];
|
char pidfile[MAX_BUFFER_SIZE];
|
||||||
|
char user[128];
|
||||||
|
char chroot[MAX_BUFFER_SIZE];
|
||||||
|
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
static struct option longopts[] = {
|
static struct option longopts[] = {
|
||||||
{ "listen", required_argument, NULL, 'l' },
|
{ "listen", required_argument, NULL, 'l' },
|
||||||
{ "bind", required_argument, NULL, 'b' },
|
{ "bind", required_argument, NULL, 'b' },
|
||||||
{ "dest", required_argument, NULL, 'd' },
|
{ "to", required_argument, NULL, 't' },
|
||||||
{ "version", no_argument, NULL, 'v' },
|
{ "version", no_argument, NULL, 'V' },
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "verbose", no_argument, NULL, 'V' },
|
{ "verbose", no_argument, NULL, 'v' },
|
||||||
{ "foreground",no_argument, NULL, 'f' },
|
{ "daemon", no_argument, NULL, 'd' },
|
||||||
{ "pidfile", required_argument, NULL, 'p' },
|
{ "pidfile", required_argument, NULL, 'p' },
|
||||||
|
{ "user", required_argument, NULL, 'u' },
|
||||||
|
{ "chroot", required_argument, NULL, 'c' },
|
||||||
};
|
};
|
||||||
|
|
||||||
if( argc < 2 ) {
|
if( argc < 2 ) {
|
||||||
@@ -112,23 +136,27 @@ int main ( int argc, char* argv[] ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
srcip = dstip = inip = dstpt = inpt = NULL;
|
srcip = dstip = inip = dstpt = inpt = NULL;
|
||||||
strncpy(pidfile, "/var/run/udpxd.pid", 19);
|
|
||||||
|
|
||||||
while ((opt = getopt_long(argc, argv, "l:b:d:vfVh?", longopts, NULL)) != -1) {
|
/* set defaults */
|
||||||
|
strncpy(pidfile, "/var/run/udpxd.pid", 19);
|
||||||
|
strncpy(user, "nobody", 7);
|
||||||
|
strncpy(chroot, "/var/empty", 11);
|
||||||
|
|
||||||
|
while ((opt = getopt_long(argc, argv, "l:b:t:u:c:vdVh?", longopts, NULL)) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'v':
|
case 'V':
|
||||||
fprintf(stderr, "This is %s version %s\n", argv[0], UDPXD_VERSION);
|
fprintf(stderr, "This is %s version %s\n", argv[0], UDPXD_VERSION);
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'd':
|
||||||
FORKED = 0;
|
FORKED = 1;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
case '?':
|
case '?':
|
||||||
usage();
|
usage();
|
||||||
return 1;
|
return 1;
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'v':
|
||||||
VERBOSE = 1;
|
VERBOSE = 1;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
@@ -139,7 +167,7 @@ int main ( int argc, char* argv[] ) {
|
|||||||
err = 1;
|
err = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 't':
|
||||||
dstip = malloc(INET6_ADDRSTRLEN+1);
|
dstip = malloc(INET6_ADDRSTRLEN+1);
|
||||||
dstpt = malloc(6);
|
dstpt = malloc(6);
|
||||||
if (parse_ip(optarg, dstip, dstpt) != 0) {
|
if (parse_ip(optarg, dstip, dstpt) != 0) {
|
||||||
@@ -158,6 +186,12 @@ int main ( int argc, char* argv[] ) {
|
|||||||
case 'p':
|
case 'p':
|
||||||
strncpy(pidfile, optarg, strlen(optarg));
|
strncpy(pidfile, optarg, strlen(optarg));
|
||||||
break;
|
break;
|
||||||
|
case 'u':
|
||||||
|
strncpy(user, optarg, strlen(optarg));
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
strncpy(chroot, optarg, strlen(optarg));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
return 1;
|
return 1;
|
||||||
@@ -172,7 +206,7 @@ int main ( int argc, char* argv[] ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(dstip == NULL) {
|
if(dstip == NULL) {
|
||||||
fprintf(stderr, "-d parameter is required!\n");
|
fprintf(stderr, "-t parameter is required!\n");
|
||||||
usage();
|
usage();
|
||||||
err = 1;
|
err = 1;
|
||||||
}
|
}
|
||||||
@@ -185,7 +219,7 @@ int main ( int argc, char* argv[] ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(! err) {
|
if(! err) {
|
||||||
err = start_listener (inip, inpt, srcip, dstip, dstpt, pidfile);
|
err = start_listener (inip, inpt, srcip, dstip, dstpt, pidfile, chroot, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(srcip != NULL)
|
if(srcip != NULL)
|
||||||
@@ -201,20 +235,3 @@ int main ( int argc, char* argv[] ) {
|
|||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void usage() {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Usage: udpxd [-lbdfpvhV]\n\n"
|
|
||||||
"Options:\n"
|
|
||||||
"--listen -l <ip:port> listen for incoming requests\n"
|
|
||||||
"--bind -b <ip> bind ip used for outgoing requests\n"
|
|
||||||
"--dest -d <ip:port> destination to forward requests to\n"
|
|
||||||
"--foreground -f don't fork into background\n"
|
|
||||||
"--pidfile -p <file> pidfile, default: /var/run/udpxd.pid\n"
|
|
||||||
"--help -h -? print help message\n"
|
|
||||||
"--version -v print program version\n"
|
|
||||||
"--verbose -V enable verbose logging\n\n"
|
|
||||||
"Options -l and -d are mandatory.\n\n"
|
|
||||||
"This is udpxd version %s.\n", UDPXD_VERSION
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|||||||
2
udpxd.h
2
udpxd.h
@@ -36,7 +36,7 @@
|
|||||||
#include <sys/fcntl.h>
|
#include <sys/fcntl.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#define UDPXD_VERSION "0.0.2"
|
#define UDPXD_VERSION "0.0.3"
|
||||||
|
|
||||||
|
|
||||||
void usage();
|
void usage();
|
||||||
|
|||||||
43
udpxd.pod
43
udpxd.pod
@@ -9,12 +9,14 @@ udpxd - A general purpose UDP relay/port forwarder/proxy
|
|||||||
Options:
|
Options:
|
||||||
--listen -l <ip:port> listen for incoming requests
|
--listen -l <ip:port> listen for incoming requests
|
||||||
--bind -b <ip> bind ip used for outgoing requests
|
--bind -b <ip> bind ip used for outgoing requests
|
||||||
--dest -d <ip:port> destination to forward requests to
|
--to -t <ip:port> destination to forward requests to
|
||||||
--foreground -f don't fork into background
|
--daemon -d daemon mode, fork into background
|
||||||
--pidfile -p <file> pidfile, default: /var/run/udpxd.pid
|
--pidfile -p <file> pidfile, default: /var/run/udpxd.pid
|
||||||
|
--user -u <user> run as user (only in daemon mode)
|
||||||
|
--chroot -c <path> chroot to <path> (only in daemon mode)
|
||||||
--help -h -? print help message
|
--help -h -? print help message
|
||||||
--version -v print program version
|
--version -V print program version
|
||||||
--verbose -V enable verbose logging
|
--verbose -v enable verbose logging
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
@@ -25,7 +27,7 @@ for outgoing packets.
|
|||||||
|
|
||||||
It listens on the ip address and port specified with B<-l>
|
It listens on the ip address and port specified with B<-l>
|
||||||
and waits for incoming udp packets. If one arrives, it sends
|
and waits for incoming udp packets. If one arrives, it sends
|
||||||
it to the destination specified with B<-d>. Responses will
|
it to the destination specified with B<-t>. Responses will
|
||||||
be sent back accordingly.
|
be sent back accordingly.
|
||||||
|
|
||||||
If B<-b> has not been specified, udpxd uses the operating
|
If B<-b> has not been specified, udpxd uses the operating
|
||||||
@@ -35,23 +37,27 @@ binds to the given ip address and uses this as the source
|
|||||||
address.
|
address.
|
||||||
|
|
||||||
In any case, udpxd behaves like a proxy. The receiving end
|
In any case, udpxd behaves like a proxy. The receiving end
|
||||||
(B<-d>) only sees the source ip address of the outgoing
|
(B<-t>) only sees the source ip address of the outgoing
|
||||||
interface of the system running udpxd or the address specified
|
interface of the system running udpxd or the address specified
|
||||||
with B<-b>.
|
with B<-b>.
|
||||||
|
|
||||||
The options B<-l> and B<-d> are mandatory.
|
The options B<-l> and B<-t> are mandatory.
|
||||||
|
|
||||||
If the option B<-f> has not been specified, udpxd forks into
|
If the option B<-d> has been specified, udpxd forks into
|
||||||
the background and becomes a daemon. It writes it pidfile to
|
the background and becomes a daemon. It writes it pidfile to
|
||||||
C</var/run/udpxd.pid>, which can be changed with the B<-p>
|
C</var/run/udpxd.pid>, which can be changed with the B<-p>
|
||||||
option.
|
option. If started as root, it also drops privileges to the
|
||||||
|
user C<nobody> or the user specified with B<-u> and chroots
|
||||||
|
to C</var/empty> or the directory specified with B<-c>. udpxd
|
||||||
|
will log to syslog facility user.info if B<-v> is specified and
|
||||||
|
if running in daemon mode.
|
||||||
|
|
||||||
B<Caution: udpxd does not drop its privileges. If started as
|
B<Caution: if not running in daemon mode, udpxd does not drop
|
||||||
root, it will continue to run as root. This may change in the
|
its privileges and will continue to run as root (if started as
|
||||||
future.>
|
root).>
|
||||||
|
|
||||||
Udpxd supports ip version 4 and 6, it doesn't support hostnames,
|
Udpxd supports ip version 4 and 6, it doesn't support hostnames,
|
||||||
-l, -d and -b must be ip addresses. In order to specify an ipv6
|
B<-l>, B<-t> and B<-b> must be ip addresses. In order to specify an ipv6
|
||||||
address and a port, use:
|
address and a port, use:
|
||||||
|
|
||||||
-l [::1]:53
|
-l [::1]:53
|
||||||
@@ -80,7 +86,7 @@ And let's say, you have a client in network 10.0.0.0/24 who whiches to reach
|
|||||||
an ntp server in network 192.168.1.0/24; and you dont operate a
|
an ntp server in network 192.168.1.0/24; and you dont operate a
|
||||||
firewall, nat or routing on 'foo'. Run udpxd like this:
|
firewall, nat or routing on 'foo'. Run udpxd like this:
|
||||||
|
|
||||||
udpxd -l 10.0.0.1:123 -d 192.168.1.199:123
|
udpxd -l 10.0.0.1:123 -t 192.168.1.199:123
|
||||||
|
|
||||||
Now, if a client with the source ip address 10.0.0.110 sends
|
Now, if a client with the source ip address 10.0.0.110 sends
|
||||||
a ntp request to 10.0.0.1:123, udpxd will forward that
|
a ntp request to 10.0.0.1:123, udpxd will forward that
|
||||||
@@ -104,7 +110,7 @@ of the interface for outgoing packets.
|
|||||||
In order to use 192.168.1.45 as the source ip address, use the
|
In order to use 192.168.1.45 as the source ip address, use the
|
||||||
B<-b> parameter:
|
B<-b> parameter:
|
||||||
|
|
||||||
udpxd -l 10.0.0.1:123 -d 192.168.1.199:123 -b 192.168.1.45
|
udpxd -l 10.0.0.1:123 -t 192.168.1.199:123 -b 192.168.1.45
|
||||||
|
|
||||||
In this case for the client everything looks as before, but the
|
In this case for the client everything looks as before, but the
|
||||||
ntp server on the other end will see ntp requests coming from
|
ntp server on the other end will see ntp requests coming from
|
||||||
@@ -113,17 +119,16 @@ ntp server on the other end will see ntp requests coming from
|
|||||||
Here we listen on the ip v6 loopback address and forward traffic
|
Here we listen on the ip v6 loopback address and forward traffic
|
||||||
to another ip v6 destination address:
|
to another ip v6 destination address:
|
||||||
|
|
||||||
udpxd -l [::1]:53 -d [2001:4860:4860::8888]:53
|
udpxd -l [::1]:53 -t [2001:4860:4860::8888]:53
|
||||||
|
|
||||||
Or, we could listen on an ip v4 address and forward to an ip v6
|
Or, we could listen on an ip v4 address and forward to an ip v6
|
||||||
address:
|
address:
|
||||||
|
|
||||||
udpxd -l 192.168.1.1:53 -d [2001:4860:4860::8888]:53
|
udpxd -l 192.168.1.1:53 -t [2001:4860:4860::8888]:53
|
||||||
|
|
||||||
=head1 FILES
|
=head1 FILES
|
||||||
|
|
||||||
B</var/run/udpxd.pid>: created if running in daemon mode (-f not
|
B</var/run/udpxd.pid>: created if running in daemon mode (B<-d>).
|
||||||
specified).
|
|
||||||
|
|
||||||
=head1 BUGS
|
=head1 BUGS
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user