mirror of
https://github.com/tmate-io/tmate-ssh-server.git
synced 2020-11-18 19:53:51 -08:00
Add PROXY protocol support
This commit is contained in:
parent
07bea82ab2
commit
4555d8d6fb
@ -1,8 +1,12 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
if [ "${USE_PROXY_PROTOCOL}" == "1" ]; then
|
||||||
|
set -- -x
|
||||||
|
fi
|
||||||
|
|
||||||
if [ "${HAS_WEBSOCKET}" == "1" ]; then
|
if [ "${HAS_WEBSOCKET}" == "1" ]; then
|
||||||
set -- -x localhost "$@"
|
set -- -w localhost "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -z "${SSH_HOSTNAME}" ]; then
|
if [ ! -z "${SSH_HOSTNAME}" ]; then
|
||||||
|
10
tmate-main.c
10
tmate-main.c
@ -41,6 +41,7 @@ struct tmate_settings _tmate_settings = {
|
|||||||
.websocket_port = TMATE_DEFAULT_WEBSOCKET_PORT,
|
.websocket_port = TMATE_DEFAULT_WEBSOCKET_PORT,
|
||||||
.tmate_host = NULL,
|
.tmate_host = NULL,
|
||||||
.log_level = LOG_NOTICE,
|
.log_level = LOG_NOTICE,
|
||||||
|
.use_proxy_protocol = false,
|
||||||
.use_syslog = false,
|
.use_syslog = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -103,7 +104,7 @@ void request_server_termination(void)
|
|||||||
|
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "usage: tmate-ssh-server [-b ip] [-h hostname] [-k keys_dir] [-a authorized_keys_path] [-p port] [-x websocket_hostname] [-q websocket_port] [-s] [-v]\n");
|
fprintf(stderr, "usage: tmate-ssh-server [-b ip] [-h hostname] [-k keys_dir] [-a authorized_keys_path] [-p port] [-w websocket_hostname] [-q websocket_port] [-x] [-s] [-v]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* get_full_hostname(void)
|
static char* get_full_hostname(void)
|
||||||
@ -156,7 +157,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
{
|
{
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "b:h:k:a:p:x:q:sv")) != -1) {
|
while ((opt = getopt(argc, argv, "b:h:k:a:p:w:q:xsv")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'b':
|
case 'b':
|
||||||
tmate_settings->bind_addr = xstrdup(optarg);
|
tmate_settings->bind_addr = xstrdup(optarg);
|
||||||
@ -173,12 +174,15 @@ int main(int argc, char **argv, char **envp)
|
|||||||
case 'p':
|
case 'p':
|
||||||
tmate_settings->ssh_port = atoi(optarg);
|
tmate_settings->ssh_port = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'w':
|
||||||
tmate_settings->websocket_hostname = xstrdup(optarg);
|
tmate_settings->websocket_hostname = xstrdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
tmate_settings->websocket_port = atoi(optarg);
|
tmate_settings->websocket_port = atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
tmate_settings->use_proxy_protocol = true;
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
tmate_settings->use_syslog = true;
|
tmate_settings->use_syslog = true;
|
||||||
break;
|
break;
|
||||||
|
@ -278,7 +278,7 @@ static void client_bootstrap(struct tmate_session *_session)
|
|||||||
/* never reached */
|
/* never reached */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_client_ip(int fd, char *dst, size_t len)
|
static int get_client_ip_socket(int fd, char *dst, size_t len)
|
||||||
{
|
{
|
||||||
struct sockaddr sa;
|
struct sockaddr sa;
|
||||||
socklen_t sa_len = sizeof(sa);
|
socklen_t sa_len = sizeof(sa);
|
||||||
@ -305,6 +305,62 @@ static int get_client_ip(int fd, char *dst, size_t len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void read_single_line(int fd, char *dst, size_t len)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This reads exactly one line from fd.
|
||||||
|
* We cannot read bytes after the new line.
|
||||||
|
* We could use recv() with MSG_PEEK to do this more efficiently.
|
||||||
|
*/
|
||||||
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
if (read(fd, &dst[i], 1) <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (dst[i] == '\r')
|
||||||
|
i--;
|
||||||
|
|
||||||
|
if (dst[i] == '\n') {
|
||||||
|
dst[i] = '\0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmate_fatal("Cannot read proxy header. Load balancer may be misconfigured");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_client_ip_proxy_protocol(int fd, char *dst, size_t len)
|
||||||
|
{
|
||||||
|
char header[110];
|
||||||
|
const char *signature = "PROXY ";
|
||||||
|
|
||||||
|
if (read(fd, header, strlen(signature)) != (ssize_t)strlen(signature))
|
||||||
|
tmate_fatal("Cannot read proxy header");
|
||||||
|
|
||||||
|
if (memcmp(header, signature, strlen(signature)))
|
||||||
|
tmate_fatal("No proxy header found. Load balancer may be misconfigured");
|
||||||
|
|
||||||
|
read_single_line(fd, header, sizeof(header));
|
||||||
|
|
||||||
|
int tok_num = 0;
|
||||||
|
for (char *tok = strtok(header, " "); tok; tok = strtok(NULL, " "), tok_num++) {
|
||||||
|
if (tok_num == 1)
|
||||||
|
strncpy(dst, tok, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tok_num != 5)
|
||||||
|
tmate_fatal("Proxy header is invalid");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_client_ip(int fd, char *dst, size_t len)
|
||||||
|
{
|
||||||
|
if (tmate_settings->use_proxy_protocol)
|
||||||
|
return get_client_ip_proxy_protocol(fd, dst, len);
|
||||||
|
else
|
||||||
|
return get_client_ip_socket(fd, dst, len);
|
||||||
|
}
|
||||||
|
|
||||||
static void ssh_log_function(int priority, const char *function,
|
static void ssh_log_function(int priority, const char *function,
|
||||||
const char *buffer, __unused void *userdata)
|
const char *buffer, __unused void *userdata)
|
||||||
{
|
{
|
||||||
@ -426,7 +482,7 @@ void tmate_ssh_server_main(struct tmate_session *session, const char *keys_dir,
|
|||||||
alarm(TMATE_SSH_GRACE_PERIOD);
|
alarm(TMATE_SSH_GRACE_PERIOD);
|
||||||
|
|
||||||
if (get_client_ip(fd, client->ip_address, sizeof(client->ip_address)) < 0)
|
if (get_client_ip(fd, client->ip_address, sizeof(client->ip_address)) < 0)
|
||||||
tmate_fatal("Error getting Client IP from connection");
|
tmate_fatal("Error getting client IP from connection");
|
||||||
|
|
||||||
tmate_info("Connection accepted ip=%s", client->ip_address);
|
tmate_info("Connection accepted ip=%s", client->ip_address);
|
||||||
|
|
||||||
|
1
tmate.h
1
tmate.h
@ -216,6 +216,7 @@ struct tmate_settings {
|
|||||||
const char *tmate_host;
|
const char *tmate_host;
|
||||||
const char *bind_addr;
|
const char *bind_addr;
|
||||||
int log_level;
|
int log_level;
|
||||||
|
bool use_proxy_protocol;
|
||||||
bool use_syslog;
|
bool use_syslog;
|
||||||
};
|
};
|
||||||
extern struct tmate_settings *tmate_settings;
|
extern struct tmate_settings *tmate_settings;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user