Skip to content

Commit

Permalink
Merge branch 'dlundquist:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
hnkeyang authored Jan 16, 2025
2 parents e05cce3 + 2d99653 commit 3366f0b
Show file tree
Hide file tree
Showing 21 changed files with 167 additions and 93 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ compiler:
- gcc
install:
- sudo apt-get update
- DEBIAN_FRONTEND=noninteractive sudo apt-get install -y apache2-utils cdbs dh-autoreconf devscripts libev-dev libpcre3-dev libudns-dev lintian rpm valgrind
- DEBIAN_FRONTEND=noninteractive sudo apt-get install -y apache2-utils cdbs dh-autoreconf devscripts libev-dev libpcre2-dev libudns-dev lintian rpm valgrind
- mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
- ./autogen.sh
script:
Expand Down
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
2023-03-16 Dustin Lundquist <[email protected]>
0.6.1 Release

* Fix buffer overflow in address module
* Fix tests

2018-12-05 Dustin Lundquist <[email protected]>
0.6.0 Release

Expand Down
37 changes: 30 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,39 @@ the initial request of the TCP session. This enables HTTPS name-based virtual
hosting to separate backend servers without installing the private key on the
proxy machine.

Status: Deprecated
------------------
2023-12-13

When I started this project, there wasn't another proxy that filled this niche.
Now, there are many proxies available to proxy layer-4 based on the TLS SNI
extension, including Nginx. Additionally, web traffic is evolving: with HTTP/2,
multiple hostnames can be multiplexed in a single TCP stream [preventing SNI
Proxy](https://github.com/dlundquist/sniproxy/issues/178) from routing it
correctly based on hostname, and HTTP/3 (QUIC) uses UDP transport. SNI Proxy
just doesn't support these protocols, and adding support for them would
complicate it significantly. For these reasons, I'm transitioning SNI Proxy to
a deprecated status.

Honestly, this has been the case for last several years, and I hadn't published
anything to that affect. With CVE-2023-25076 it became clear that this
situation needs to be communicated clearly.

In some cases, SNI Proxy might be a better fit than a more general purpose
proxy, so I'm not going to abandon the project completely. I'll still monitor
issues and email requests; however, unless it is a significant security or
reliablity issue, don't expect a response.

Features
--------
+ Name-based proxying of HTTPS without decrypting traffic. No keys or
certificates required.
+ Supports both TLS and HTTP protocols.
+ Supports IPv4, IPv6 and Unix domain sockets for both back end servers and
+ Supports IPv4, IPv6 and Unix domain sockets for both back-end servers and
listeners.
+ Supports multiple listening sockets per instance.
+ Supports HAProxy proxy protocol to propagate original source address to
backend servers.
back-end servers.

Usage
-----
Expand All @@ -35,20 +58,20 @@ For Debian or Fedora based Linux distributions see building packages below.
**Prerequisites**

+ Autotools (autoconf, automake, gettext and libtool)
+ libev4, libpcre and libudns development headers
+ libev4, libpcre2 (or libpcre) and libudns development headers
+ Perl and cURL for test suite

**Install**

./autogen.sh && ./configure && make check && sudo make install
./autogen.sh && ./checonfigure --enable-dns && make check && sudo make install

**Building Debian/Ubuntu package**

This is the preferred installation method on recent Debian based distributions:

1. Install required packages

sudo apt-get install autotools-dev cdbs debhelper dh-autoreconf dpkg-dev gettext libev-dev libpcre3-dev libudns-dev pkg-config fakeroot devscripts
sudo apt-get install autotools-dev cdbs debhelper dh-autoreconf dpkg-dev gettext libev-dev libpcre2-dev libudns-dev pkg-config fakeroot devscripts

2. Build a Debian package

Expand All @@ -68,7 +91,7 @@ This is the preferred installation method for modern Fedora based distributions.

2. Build a distribution tarball:

./autogen.sh && ./configure && make dist
./autogen.sh && ./configure --enable-dns && make dist

3. Build a RPM package

Expand All @@ -95,7 +118,7 @@ may not even work.

3. Make it so

./autogen.sh && ./configure && make
./autogen.sh && ./configure --enable-dns && make

OS X support is a best effort, and isn't a primary target platform.

Expand Down
76 changes: 14 additions & 62 deletions configure.ac
Original file line number Diff line number Diff line change
@@ -1,83 +1,35 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.60])
AC_INIT([sniproxy], [0.6.0])
AC_CONFIG_SRCDIR([src/sniproxy.c])
AC_CONFIG_MACRO_DIR([m4])
AC_PREREQ([2.71])
AC_INIT([sniproxy],[0.6.1])
AM_INIT_AUTOMAKE([subdir-objects])
AM_SILENT_RULES([yes])
AC_GNU_SOURCE
AC_USE_SYSTEM_EXTENSIONS

# Checks for programs.
AC_PROG_CC_C99
# Required by automake < 1.14
AC_PROG_CC
AM_PROG_CC_C_O


# Checks for libraries.
PKG_CHECK_MODULES([LIBEV], [libev], HAVE_LIBEV=yes; AC_DEFINE(HAVE_LIBEV, 1),
[AC_LIB_HAVE_LINKFLAGS(ev,, [#include <ev.h>], [ev_run(0,0);])
if test x$ac_cv_libev = xyes; then
AC_SUBST([LIBEV_LIBS], [$LIBEV])
else
AC_MSG_ERROR([[***
*** libev4 was not found.
***]])
fi
])

PKG_CHECK_MODULES([LIBPCRE], [libpcre], HAVE_LIBPCRE=yes; AC_DEFINE(HAVE_LIBPCRE, 1),
[AC_LIB_HAVE_LINKFLAGS(pcre,, [#include <pcre.h>], [pcre_exec(0,0,0,0,0,0,0,0);])
if test x$ac_cv_libpcre = xyes; then
AC_SUBST([LIBPCRE_LIBS], [$LIBPCRE])
else
AC_MSG_ERROR([[***
*** libpcre was not found.
***]])
fi
])
AC_CHECK_LIB([ev], [ev_run], [],
[AC_MSG_ERROR([libev is required])])
AC_CHECK_LIB([pcre2-8], [pcre2_compile_8], [],
[AC_CHECK_LIB([pcre], [pcre_exec], [],
[AC_MSG_ERROR([libpcre is required])])])

AC_ARG_ENABLE([dns],
[AS_HELP_STRING([--disable-dns], [Disable DNS resolution])],
[dns="$withval"], [dns=yes])
[AS_HELP_STRING([--enable-dns], [Enable DNS resolution])])

AM_CONDITIONAL([DNS_ENABLED], [test "x$dns" = "xyes"])
AM_CONDITIONAL([DNS_ENABLED], [test "$enable_dns"])

AS_IF([test "x$dns" = "xyes"],
[PKG_CHECK_MODULES([LIBUDNS], [libudns], HAVE_LIBUDNS=yes; AC_DEFINE(HAVE_LIBUDNS, 1),
[AC_LIB_HAVE_LINKFLAGS(udns,, [#include <udns.h>], [dns_init(0, 0);])
AS_IF([test x$ac_cv_libudns = xyes], [AC_SUBST([LIBUDNS_LIBS], [$LIBUDNS])])
])
])
AS_IF([test "$enable_dns"],
[AC_CHECK_LIB([udns], [dns_init])])

AC_ARG_ENABLE([rfc3339-timestamps],
[AS_HELP_STRING([--enable-rfc3339-timestamps], [Enable RFC3339 timestamps])],
[rfc3339_timestamps=${enableval}], [rfc3339_timestamps=no])

AS_IF([test "x$rfc3339_timestamps" = "xyes"],
[AC_DEFINE([RFC3339_TIMESTAMP], 1, [RFC3339 timestamps enabled])])

# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h strings.h sys/socket.h sys/time.h syslog.h unistd.h],,
AC_MSG_ERROR([required header(s) not found]))

# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
AC_TYPE_PID_T
AC_TYPE_UID_T
AC_TYPE_SIZE_T
AC_TYPE_SSIZE_T
AC_TYPE_UINT16_T
AC_TYPE_UINT8_T

# Checks for library functions.
AC_FUNC_FORK
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_FUNC_STRTOD
AC_CHECK_FUNCS([atexit daemon memset socket strcasecmp strchr strdup strerror strncasecmp strrchr strspn strtoul],,
AC_MSG_ERROR([required functions(s) not found]))
[AC_DEFINE([RFC3339_TIMESTAMP], 1, [RFC3339 timestamps enabled])])

AC_CHECK_FUNCS([accept4])

Expand Down
15 changes: 14 additions & 1 deletion debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
sniproxy (0.6.1) UNRELEASED; urgency=medium

* New git revision

-- Dustin Lundquist <[email protected]> Thu, 14 Dec 2023 09:40:47 -0800

sniproxy (0.6.1) unstable; urgency=high

* Fix buffer overflow in address module
* Fix tests

-- Dustin Lundquist <[email protected]> Thu, 16 Mar 2023 21:53:48 -0700

sniproxy (0.6.0) unstable; urgency=medium

* PROXY v1 protocol support
Expand All @@ -10,7 +23,7 @@ sniproxy (0.6.0) unstable; urgency=medium
sniproxy (0.5.0) unstable; urgency=medium

* Transparent proxy support
* Use accept4() on Linix
* Use accept4() on Linux
* Run as group specified in config

-- Dustin Lundquist <[email protected]> Wed, 26 Apr 2017 07:17:13 -0700
Expand Down
2 changes: 1 addition & 1 deletion debian/compat
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8
10
2 changes: 1 addition & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Source: sniproxy
Section: web
Priority: optional
Maintainer: Dustin Lundquist <[email protected]>
Build-Depends: cdbs, debhelper (>= 8.0.0), dh-autoreconf, autotools-dev, gettext, pkg-config, libev-dev (>= 4.0), libpcre3-dev, libudns-dev
Build-Depends: cdbs, debhelper (>= 8.0.0), dh-autoreconf, autotools-dev, gettext, pkg-config, libev-dev (>= 4.0), libpcre2-dev | libpcre3-dev, libudns-dev
Standards-Version: 3.9.5
Vcs-Git: https://github.com/dlundquist/sniproxy.git
Vcs-Browser: https://github.com/dlundquist/sniproxy
Expand Down
12 changes: 7 additions & 5 deletions debian/rules
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#!/usr/bin/make -f

include /usr/share/cdbs/1/rules/debhelper.mk
include /usr/share/cdbs/1/class/autotools.mk
include /usr/share/cdbs/1/rules/autoreconf.mk
%:
dh $@

CDBS_BUILD_DEPENDS += , dh-autoreconf
override_dh_auto_configure:
dh_auto_configure -- --enable-dns

install/sniproxy::
override_dh_auto_test:

execute_after_dh_install-indep:
install -D -m 644 debian/sniproxy.conf debian/sniproxy/etc/sniproxy.conf
install -D -m 644 debian/logrotate.conf debian/sniproxy/etc/logrotate.d/sniproxy.conf
install -d -m 750 -o daemon -g adm debian/sniproxy/var/log/sniproxy
Expand Down
6 changes: 5 additions & 1 deletion redhat/sniproxy.spec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: sniproxy
Version: 0.6.0
Version: 0.6.1
Release: 1%{?dist}
Summary: Transparent TLS and HTTP layer 4 proxy with SNI support

Expand Down Expand Up @@ -46,6 +46,10 @@ rm -rf $RPM_BUILD_ROOT


%changelog
* Thu Mar 16 2023 Dustin Lundquist <[email protected] 0.6.1-1
- Fix buffer overflow in address module
- Fix tests

* Wed Dec 5 2018 Dustin Lundquist <[email protected]> 0.6.0-1
- PROXY v1 protocol support
- SO_REUSEPORT support on Linux 3.9 and later
Expand Down
2 changes: 1 addition & 1 deletion setver.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

VERSION=0.6.0
VERSION=0.6.1

SOURCE_DIR=$(dirname $0)
GIT_DIR=${SOURCE_DIR}/.git
Expand Down
3 changes: 0 additions & 3 deletions src/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
AM_CPPFLAGS = $(LIBEV_CFLAGS) $(LIBPCRE_CFLAGS) $(LIBUDNS_CFLAGS)
AM_CFLAGS = -fno-strict-aliasing -Wall -Wextra -Wpedantic -Wwrite-strings

sbin_PROGRAMS = sniproxy
Expand Down Expand Up @@ -33,5 +32,3 @@ sniproxy_SOURCES = sniproxy.c \
table.h \
tls.c \
tls.h

sniproxy_LDADD = $(LIBEV_LIBS) $(LIBPCRE_LIBS) $(LIBUDNS_LIBS)
2 changes: 2 additions & 0 deletions src/address.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ new_address(const char *hostname_or_ip) {
if (hostname_or_ip[0] == '[' &&
(port = strchr(hostname_or_ip, ']')) != NULL) {
len = (size_t)(port - hostname_or_ip - 1);
if (len >= INET6_ADDRSTRLEN)
return NULL;

/* inet_pton() will not parse the IP correctly unless it is in a
* separate string.
Expand Down
29 changes: 28 additions & 1 deletion src/backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/queue.h>
#include <pcre.h>
#include <assert.h>
#include "backend.h"
#include "address.h"
Expand Down Expand Up @@ -105,6 +105,19 @@ add_backend(struct Backend_head *backends, struct Backend *backend) {
int
init_backend(struct Backend *backend) {
if (backend->pattern_re == NULL) {

#if defined(HAVE_LIBPCRE2_8)
int reerr;
size_t reerroffset;

backend->pattern_re =
pcre2_compile((const uint8_t *)backend->pattern, PCRE2_ZERO_TERMINATED, 0, &reerr, &reerroffset, NULL);
if (backend->pattern_re == NULL) {
err("Regex compilation of \"%s\" failed: %d, offset %zu",
backend->pattern, reerr, reerroffset);
return 0;
}
#elif defined(HAVE_LIBPCRE)
const char *reerr;
int reerroffset;

Expand All @@ -115,6 +128,7 @@ init_backend(struct Backend *backend) {
backend->pattern, reerr, reerroffset);
return 0;
}
#endif

char address[ADDRESS_BUFFER_SIZE];
debug("Parsed %s %s",
Expand All @@ -137,9 +151,17 @@ lookup_backend(const struct Backend_head *head, const char *name, size_t name_le

STAILQ_FOREACH(iter, head, entries) {
assert(iter->pattern_re != NULL);
#if defined(HAVE_LIBPCRE2_8)
pcre2_match_data *md = pcre2_match_data_create_from_pattern(iter->pattern_re, NULL);
int ret = pcre2_match(iter->pattern_re, (const uint8_t *)name, name_len, 0, 0, md, NULL);
pcre2_match_data_free(md);
if (ret >= 0)
return iter;
#elif defined(HAVE_LIBPCRE)
if (pcre_exec(iter->pattern_re, NULL,
name, name_len, 0, 0, NULL, 0) >= 0)
return iter;
#endif
}

return NULL;
Expand Down Expand Up @@ -176,7 +198,12 @@ free_backend(struct Backend *backend) {

free(backend->pattern);
free(backend->address);
#if defined(HAVE_LIBPCRE2_8)
if (backend->pattern_re != NULL)
pcre2_code_free(backend->pattern_re);
#elif defined(HAVE_LIBPCRE)
if (backend->pattern_re != NULL)
pcre_free(backend->pattern_re);
#endif
free(backend);
}
Loading

0 comments on commit 3366f0b

Please sign in to comment.