mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
socket-proxyd: Add --listener option for listener/destination pairs.
This commit is contained in:
parent
828db5d84a
commit
adcf4c81c5
1
TODO
1
TODO
@ -105,7 +105,6 @@ Features:
|
|||||||
* remove NSS usage from PID 1 (notably the specifiers)
|
* remove NSS usage from PID 1 (notably the specifiers)
|
||||||
|
|
||||||
* socket-proxyd:
|
* socket-proxyd:
|
||||||
- Support multiple inherited sockets mapped to different remote hosts
|
|
||||||
- Use a nonblocking alternative to getaddrinfo
|
- Use a nonblocking alternative to getaddrinfo
|
||||||
- Until we can start daemons directly, find a less ugly, less racy alternative than shell scripts for the second man page example.
|
- Until we can start daemons directly, find a less ugly, less racy alternative than shell scripts for the second man page example.
|
||||||
- Support starting daemons directly without requiring a shell script; update man pages
|
- Support starting daemons directly without requiring a shell script; update man pages
|
||||||
|
@ -31,6 +31,12 @@
|
|||||||
<surname>Strauss</surname>
|
<surname>Strauss</surname>
|
||||||
<email>david@davidstrauss.net</email>
|
<email>david@davidstrauss.net</email>
|
||||||
</author>
|
</author>
|
||||||
|
<author>
|
||||||
|
<contrib>Developer</contrib>
|
||||||
|
<firstname>Lennart</firstname>
|
||||||
|
<surname>Poettering</surname>
|
||||||
|
<email>lennart@poettering.net</email>
|
||||||
|
</author>
|
||||||
</authorgroup>
|
</authorgroup>
|
||||||
</refentryinfo>
|
</refentryinfo>
|
||||||
<refmeta>
|
<refmeta>
|
||||||
@ -83,6 +89,17 @@
|
|||||||
<title>Options</title>
|
<title>Options</title>
|
||||||
<para>The following options are understood:</para>
|
<para>The following options are understood:</para>
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-l</option></term>
|
||||||
|
<term><option>--listener</option></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Restricts listening to a
|
||||||
|
single inherited socket, specified
|
||||||
|
as a file descriptor. By default,
|
||||||
|
the proxy listens on all inherited
|
||||||
|
sockets.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-h</option></term>
|
<term><option>-h</option></term>
|
||||||
<term><option>--help</option></term>
|
<term><option>--help</option></term>
|
||||||
@ -196,8 +213,12 @@ while [ ! -f /tmp/nginx.pid ]
|
|||||||
do
|
do
|
||||||
/usr/bin/inotifywait /tmp/nginx.pid
|
/usr/bin/inotifywait /tmp/nginx.pid
|
||||||
done
|
done
|
||||||
exec /usr/bin/systemd-socket-proxyd localhost 8080]]>
|
exec /usr/bin/systemd-socket-proxyd localhost:8080]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
<para>Make it executable:</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[chmod 755 /usr/bin/socket-proxyd-nginx.sh]]>
|
||||||
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
<example label="nginx configuration">
|
<example label="nginx configuration">
|
||||||
<title>
|
<title>
|
||||||
@ -215,6 +236,63 @@ server {
|
|||||||
<![CDATA[# systemctl enable proxy-with-nginx.socket
|
<![CDATA[# systemctl enable proxy-with-nginx.socket
|
||||||
# systemctl start proxy-with-nginx.socket
|
# systemctl start proxy-with-nginx.socket
|
||||||
$ curl http://localhost:80/]]>
|
$ curl http://localhost:80/]]>
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
</refsect2>
|
||||||
|
|
||||||
|
<refsect2>
|
||||||
|
<title>Multiple Listeners with Multiple Destinations</title>
|
||||||
|
<para>When using namespaces, it may be useful to
|
||||||
|
have multiple listeners with each going to a unique
|
||||||
|
destination. systemd always passes sockets into
|
||||||
|
services in the order specified in the socket
|
||||||
|
unit, beginning with file descriptor 3.</para>
|
||||||
|
<para>In this example, port <literal>80</literal>
|
||||||
|
will proxy to <literal>localhost:8080</literal>,
|
||||||
|
and port <literal>443</literal> will proxy to
|
||||||
|
<literal>localhost:8443</literal>.</para>
|
||||||
|
<example label="proxy socket unit">
|
||||||
|
<title>/etc/systemd/system/multi-destination.socket</title>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[[Socket]
|
||||||
|
ListenStream=80
|
||||||
|
ListenStream=443
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=sockets.target]]>
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
<example label="proxy service unit">
|
||||||
|
<title>/etc/systemd/system/multi-destination.service</title>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[[Service]
|
||||||
|
ExecStart=/usr/bin/socket-proxyd-multi-destination.sh
|
||||||
|
PrivateTmp=true
|
||||||
|
PrivateNetwork=true]]>
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<example label="shell script">
|
||||||
|
<title>
|
||||||
|
/usr/bin/socket-proxyd-multi-destination.sh</title>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[#!/bin/sh
|
||||||
|
/usr/bin/systemd-socket-proxyd --listener=3 localhost:8080 &
|
||||||
|
/usr/bin/systemd-socket-proxyd --listener=4 localhost:8443 &
|
||||||
|
wait]]>
|
||||||
|
</programlisting>
|
||||||
|
<para>Make it executable:</para>
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[chmod 755 /usr/bin/socket-proxyd-multi-destination.sh]]>
|
||||||
|
</programlisting>
|
||||||
|
</example>
|
||||||
|
|
||||||
|
<example label="commands">
|
||||||
|
<programlisting>
|
||||||
|
<![CDATA[# systemctl enable multi-destination.socket
|
||||||
|
# systemctl start multi-destination.socket
|
||||||
|
$ curl http://localhost/
|
||||||
|
$ curl https://localhost/]]>
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</example>
|
</example>
|
||||||
</refsect2>
|
</refsect2>
|
||||||
|
@ -66,6 +66,7 @@ typedef struct Connection {
|
|||||||
} Connection;
|
} Connection;
|
||||||
|
|
||||||
static const char *arg_remote_host = NULL;
|
static const char *arg_remote_host = NULL;
|
||||||
|
static int arg_listener = -1;
|
||||||
|
|
||||||
static void connection_free(Connection *c) {
|
static void connection_free(Connection *c) {
|
||||||
assert(c);
|
assert(c);
|
||||||
@ -554,8 +555,9 @@ static int help(void) {
|
|||||||
printf("%s [HOST:PORT]\n"
|
printf("%s [HOST:PORT]\n"
|
||||||
"%s [SOCKET]\n\n"
|
"%s [SOCKET]\n\n"
|
||||||
"Bidirectionally proxy local sockets to another (possibly remote) socket.\n\n"
|
"Bidirectionally proxy local sockets to another (possibly remote) socket.\n\n"
|
||||||
" -h --help Show this help\n"
|
" -l --listener=FD Listen on a specific, single file descriptor.\n"
|
||||||
" --version Show package version\n",
|
" -h --help Show this help\n"
|
||||||
|
" --version Show package version\n",
|
||||||
program_invocation_short_name,
|
program_invocation_short_name,
|
||||||
program_invocation_short_name);
|
program_invocation_short_name);
|
||||||
|
|
||||||
@ -565,22 +567,22 @@ static int help(void) {
|
|||||||
static int parse_argv(int argc, char *argv[]) {
|
static int parse_argv(int argc, char *argv[]) {
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ARG_VERSION = 0x100,
|
ARG_VERSION = 0x100
|
||||||
ARG_IGNORE_ENV
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "version", no_argument, NULL, ARG_VERSION },
|
{ "version", no_argument, NULL, ARG_VERSION },
|
||||||
|
{ "listener", required_argument, NULL, 'l' },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
int c;
|
int c, fd;
|
||||||
|
|
||||||
assert(argc >= 0);
|
assert(argc >= 0);
|
||||||
assert(argv);
|
assert(argv);
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
|
while ((c = getopt_long(argc, argv, "hl:", options, NULL)) >= 0) {
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
|
||||||
@ -592,6 +594,18 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
puts(SYSTEMD_FEATURES);
|
puts(SYSTEMD_FEATURES);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
if (safe_atoi(optarg, &fd) < 0) {
|
||||||
|
log_error("Failed to parse listener file descriptor: %s", optarg);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (fd < SD_LISTEN_FDS_START) {
|
||||||
|
log_error("Listener file descriptor must be at least %d.", SD_LISTEN_FDS_START);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
arg_listener = fd;
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@ -632,19 +646,26 @@ int main(int argc, char *argv[]) {
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = sd_listen_fds(1);
|
if (arg_listener == -1) {
|
||||||
if (n < 0) {
|
n = sd_listen_fds(1);
|
||||||
log_error("Failed to receive sockets from parent.");
|
if (n < 0) {
|
||||||
r = n;
|
log_error("Failed to receive sockets from parent.");
|
||||||
goto finish;
|
r = n;
|
||||||
} else if (n == 0) {
|
goto finish;
|
||||||
log_error("Didn't get any sockets passed in.");
|
} else if (n == 0) {
|
||||||
r = -EINVAL;
|
log_error("Didn't get any sockets passed in.");
|
||||||
goto finish;
|
r = -EINVAL;
|
||||||
}
|
goto finish;
|
||||||
|
}
|
||||||
for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
|
log_info("Listening on %d inherited socket(s), starting with fd=%d.", n, SD_LISTEN_FDS_START);
|
||||||
r = add_listen_socket(&context, event, fd);
|
for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
|
||||||
|
r = add_listen_socket(&context, event, fd);
|
||||||
|
if (r < 0)
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_info("Listening on single inherited socket fd=%d.", arg_listener);
|
||||||
|
r = add_listen_socket(&context, event, arg_listener);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user