GithubHelp home page GithubHelp logo

graygnuorg / pound Goto Github PK

View Code? Open in Web Editor NEW
40.0 7.0 12.0 2.35 MB

Light-weight reverse proxy, load balancer and HTTPS front-end for Web servers.

License: GNU General Public License v3.0

Makefile 1.02% C 86.15% Shell 0.08% M4 4.81% Perl 7.82% BitBake 0.13%

pound's Issues

Different behaviour in URL parsing between versions of libpcre?

Hi, we are experiencing an odd behaviour between Pound 2.8 and Pound 4 for one backend used to wrap in HTTPS an HTTP internal server.
The URL is written as: URL ".*/AlboOnline.*"

With Pound 2.8, if we go to https://our.site/AlboOnline (no slash at the end), the internal backend server generates a "302 Redirect" to **https://**our.site/AlboOnline/ then a "302 Redirect" to https://our.site/AlboOnline/ricercaAlbo (no slash at the end) which is the desired page.

With Pound 4, if we go to https://our.site/AlboOnline (no slash at the end), the internal backend server generates a "302 Redirect" to **http://**our.site/AlboOnline which does not work.
Instead, if we go to https://our.site/AlboOnline/ (with slash at the end), the internal backend server generates a "302 Redirect" to
**http://**our.site/AlboOnline/ricercaAlbo which, of course, does not work.

Could this behaviour related to the different versions of libpcre?

openssl 0A000438 error and Caddy servers

I'm getting error for some Caddy server backends:

pound: BIO_do_handshake with xx.xx.xx.xx:443 failed: error:0A000438:SSL routines::tlsv1 alert internal error

backend configuration (inside https listener) is minimal:

       BackEnd              
           HTTPS            
           Address some.caddy.server
           Port 443         
       End                  

Playing with Disable TLSx or Ciphers options (like any other options) changed nothing.
Tested with openssl 3.0.9 and 3.1.3 – same results.

Here's Qualys report on one of "problematic" sites.
Also, this discussion on stackoverflow may be relevant to the issue

"error copy client cont" error

Using pound 4.9.90 and upgraded to 4.11.90.

We started seeing more and more of the following errors for a specific backend:

e500 for [ext ip address] error copy client cont to [backend address]/POST /EWS/mrsproxy.svc HTTP/1.1: Connection timed out (10.038 sec)

Can you help us understand what does the error mean and where the time out is set?

This is the configuration stanza in use:

    Service
            HeadRequire "Host: .*redacted*"
            URL ".*/(autodiscover|ecp|ews|EWS|mapi|Microsoft-ActiveSync|oab|owa|rpc).*"
            IgnoreCase 1
            BackEnd
                    HTTPS
                    Address redacted
                    Port 443
                    TimeOut 180
            End
    End

Regards,
AB

Unable to delete pid file when not running as root

Hi,

I see the following issue when running pound as user pound:

Apr 3 17:14:16 ns1 pound[4066]: got signal 15
Apr 3 17:14:16 ns1 pound[4069]: shutting down...
Apr 3 17:14:16 ns1 pound[4069]: can't remove file /var/run/pound/ctl_socket: Permission denied
Apr 3 17:14:16 ns1 pound[4069]: can't remove file /var/run/pound.pid: Permission denied
Apr 3 17:14:16 ns1 pound[4066]: got signal 17

I understand that this is because the files are owned by root and in fact it doesn't happen when pound is running as root.

Is this the expected behavior and the error messages should just be ignored?

Thanks,
Simon

Backed does not come back from dead status

One of our backend (Tomcat on Windows) does not come back from the "dead" status when, for some reasons, it becomes unreachable for some time.
We do not have set the "Alive" parameter.
The only way to get it back working is to restart pound.
Is there anything we can check?

Bug in chunked message body decoding causes malformed requests to be forwarded

When Pound receives a request with the Transfer-Encoding: chunked header and a malformed message body, Pound forwards that request without its message body.

To see this for yourself, send Pound the following request:

POST /  HTTP/1.1\r\n
Transfer-Encoding: chunked\r\n
\r\n
1\r0\n

It should forward something like this:

POST /  HTTP/1.1\r\n
Transfer-Encoding: chunked\r\n
X-Forwarded-For: <some ip address>\r\n
X-Forwarded-Proto: http\r\n
X-Forwarded-Port: <some port>\r\n
\r\n

This forwarded message is incomplete, and will almost certainly cause the backend to time out while it waits for the message body to arrive.

Create release of prerelease versions?

Hi Sergey,

Would it be possible that you create a release of prerelease versions like 4.8.91? Since I'm maintaining RPM packages also for older distributions, it would make it easier for me to create such prereleases and test them. Problem is, the whole GNU auto* stuff is not new enough on such systems.

Thanks,
Simon

pound on FreeBSD exits on signal 11 and reports out of memory

I've been running pound for months and regularly daily see the following kernel messages on FreeBSD 13.2-RELEASE-p11 on amd64.

Aug 2 02:58:20 webproxy kernel: pid 61930 (pound), jid 0, uid 80: exited on signal 11
Aug 2 02:58:20 webproxy pound[656]: got signal 20
Aug 2 02:58:20 webproxy pound[656]: child terminated on signal 11
Aug 2 06:10:48 webproxy kernel: pid 62161 (pound), jid 0, uid 80: exited on signal 11
Aug 2 06:10:48 webproxy pound[656]: got signal 20
Aug 2 06:10:48 webproxy pound[656]: child terminated on signal 11
Aug 2 13:07:34 webproxy kernel: pid 62854 (pound), jid 0, uid 80: exited on signal 11
Aug 2 13:07:34 webproxy pound[656]: got signal 20
Aug 2 13:07:34 webproxy pound[656]: child terminated on signal 11
Aug 3 01:05:43 webproxy kernel: pid 63329 (pound), jid 0, uid 80: exited on signal 11
Aug 3 01:05:44 webproxy pound[656]: got signal 20
Aug 3 01:05:44 webproxy pound[656]: child terminated on signal 11
Aug 3 01:26:33 webproxy kernel: pid 64153 (pound), jid 0, uid 80: exited on signal 11
Aug 3 01:26:33 webproxy pound[656]: got signal 20
Aug 3 01:26:33 webproxy pound[656]: child terminated on signal 11

I also see some daily occurrences of memory messages.

Aug 1 00:18:02 webproxy pound[59725]: out of memory
Aug 1 01:21:44 webproxy pound[59725]: out of memory
Aug 1 02:32:25 webproxy pound[59725]: out of memory
Aug 1 03:12:29 webproxy pound[60276]: out of memory
Aug 1 08:54:09 webproxy pound[60512]: out of memory
Aug 1 09:10:01 webproxy pound[60512]: out of memory
Aug 1 17:03:38 webproxy pound[61021]: out of memory
Aug 1 21:29:26 webproxy pound[61773]: out of memory
Aug 3 02:41:59 webproxy pound[64176]: out of memory
Aug 3 14:26:25 webproxy pound[64176]: out of memory
Aug 3 22:14:00 webproxy pound[64176]: out of memory

The machine has 8GB of RAM and swap space available, and is not under significant load. It only runs the pound service.

CPU: 0.2% user, 0.0% nice, 0.2% system, 0.0% interrupt, 99.6% idle
Mem: 7864K Active, 169M Inact, 677M Wired, 516M Buf, 7065M Free
Swap: 8191M Total, 8191M Free

PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND
64176 www 8 20 0 50M 14M sigwai 0 0:15 0.00% pound
656 www 1 20 0 18M 6564K sigwai 1 0:00 0.00% pound

I'm aware that 13.2 is end of life as of June 30th this year so I'll try and deploy a new setup with 14.1-RELEASE and see if the issue still persists there.

Installed version via packages is the latest on this OS:
pound-4.11_1 HTTP/HTTPS reverse-proxy and load-balancer

Let me know if I can supply any further information to investigate if this is an issue.

Multiple "Can't read BIO_f_base64" in log

We've started migrating our old pound-2.8 server to pound-4.8.90
Everything seems working fine but we have multiple "Can't read BIO_f_base64" warning in the log.
Is this harmless? Is there something we should check?
We compiled pound-4 with a buffer size of 8192 because some backend applications needed it.

GCC flag -fcommon required with GCC v. 10.2.0

Hello, I'm currently building pound to run on Photon OS (VMware Linux container).
Photon OS ships with GCC 10.2.0: the assembly steps (ld) with the following error:

gcc -pthread -g -O2   -o poundctl poundctl.o ./libpound.a -lpthread -lssl -lcrypto -lresolv -ldl -lrt
/usr/bin/ld: ./libpound.a(json.o):/root/pound-4.4/src/pound.h:792: multiple definition of `progname'; poundctl.o:/root/pound-4.4/src/pound.h:792: first defined here
/usr/bin/ld: ./libpound.a(mem.o):/root/pound-4.4/src/pound.h:792: multiple definition of `progname'; poundctl.o:/root/pound-4.4/src/pound.h:792: first defined here
/usr/bin/ld: ./libpound.a(progname.o):/root/pound-4.4/src/./pound.h:792: multiple definition of `progname'; poundctl.o:/root/pound-4.4/src/pound.h:792: first defined here
/usr/bin/ld: ./libpound.a(tmpl.o):/root/pound-4.4/src/pound.h:792: multiple definition of `progname'; poundctl.o:/root/pound-4.4/src/pound.h:792: first defined here

Setting CFLAGS=-fcommon before running configure solves the problem.
The flags is reported on multiple source to be a change in the default behaviour of GCC v. 10 and above.

Pound 4.12 segfaults with libpcre2

Hello,

pound 4.12 sporadically segfaults on Debian 12 (bookworm) with libpcre2...

kernel: [ 32.075593] pound[403]: segfault at 7f4e7c021000 ip 00007f4e9d5e00cd sp 00007f4e9d1720b0 error 4 in libpcre2-8.so.0.11.2[7f4e9d587000+6b000] likely on CPU 1 (core 1, socket 0)
kernel: [ 7541.154310] pound[13919]: segfault at 7f5b67ffffff ip 00007f5baabe39fb sp 00007f5ba9f52060 error 4 in libpcre2-8.so.0.11.2[7f5baab87000+6b000] likely on CPU 0 (core 0, socket 0)

I've compiled pound from Debian Sid... thank you, that this masterpiece is part of Debian again:)

If I compile pound from Debian Sid with libpcre3, which is described with "Old Perl 5 Compatible Regular Expression Library" than pound runs rock solid.

Sadly I currently use pound 4.12 in production environment and cannot simply do testing because of reachability.

libpcre2 on Debian 12 is currently in version 10.42-1 (New Perl Compatible Regular Expression Library)
libpcre3 on Debian 12 is currently in version 2:8.39-15 (Old Perl 5 Compatible Regular Expression Library)

Do you have a clue what is going on?
I feel in my guts that the new libpcre2 is "not that compatible" as the older libpcre3 (despite the package versioning 2 vs 3).

Pound forwards requests containing both `Transfer-Encoding` and `Content-Length` headers

When Pound receives a request containing both an unrecognized Transfer-Encoding value and a Content-Length value, both are forwarded to the backend. This violates RFC 9112, section 6.2:

A sender MUST NOT send a Content-Length header field in any message that contains a Transfer-Encoding header field.

To see this for yourself, start up Pound and send it the following request:

POST / HTTP/1.1\r\n
Host: a\r\n
Content-Length: 5\r\n
Transfer-Encoding: invalid!!\r\n
\r\n
0\r\n\r\n

You should see the following forwarded to the backend:

POST / HTTP/1.1\r\n
Host: a\r\n
Content-Length: 5\r\n
Transfer-Encoding: invalid!!\r\n
X-Forwarded-For: 172.19.0.1\r\n
X-Forwarded-Proto: http\r\n
X-Forwarded-Port: 80\r\n
\r\n
0\r\n\r\n

Note that both headers remain.

HeadRemove Bad Response & Include no longer supported in ListenHTTPS section

Hi

FreeBSD ports recently upgraded from pound 2.8 to 4.5 - and I ran across two issues with this.

  1. The directive 'HeadRemove "X-Forwarded-Proto"' now results in a 'Bad Request' response when trying to access any websites.

  2. 'Include' is no longer supported within ListenHTTPS.

For the latter, I was able to fix this with the following patch:

*** src/config.c.old    Sun Feb 12 19:56:35 2023
--- src/config.c        Sat Mar 18 20:02:12 2023
***************
*** 3387,3392 ****
--- 3387,3393 ----
  }

  static PARSER_TABLE https_parsetab[] = {
+   { "Include", parse_include },
    { "End", parse_end },
    { "Address", assign_address, NULL, offsetof (LISTENER, addr) },
    { "Port", assign_port, NULL, offsetof (LISTENER, addr) },

But a more generic case may be considered - to apply this to other sections within the configuration - but this was the only area I needed it fixed.

I did not do any further investigation on the HeadRemove issue.

Heap buffer overflow in HTTP response parser

The bug

When Pound receives certain invalid responses from backends, it may access a heap buffer out of bounds.

To reproduce

  1. Build and run the following Dockerfile:
FROM debian:trixie-slim

WORKDIR /app

RUN apt -y update && apt -y upgrade && apt -y install --no-install-recommends perl autoconf
 automake libssl-dev wget git ca-certificates build-essential texinfo ncat

RUN git clone --recurse-submodules https://github.com/graygnuorg/pound

RUN cd /app/pound && git pull && ./bootstrap && export LDFLAGS='-fsanitize=address,undefine
d' CFLAGS='-fsanitize=address,undefined -g' && ./configure && make -j$(nproc) && make insta
ll

RUN cat <<EOF > /usr/local/etc/pound.cfg
ListenHTTP
    Address 127.0.0.1
    Port 8000
    Service
        Backend
            Address 127.0.0.1
            Port 8001
        End
    End
End
EOF

RUN mkdir -p /usr/local/var/run

CMD printf 'A\r\n\r\n' | ncat -l 127.0.0.1 8001 &>/dev/null & sleep 1; pound -e & sleep 5; wget http://localhost:8000
  1. Watch Pound crash and observe the ASan output:
=================================================================
==11==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x502000005d57 at pc 0x61f3f6a99d79 bp 0x760aa27fd050 sp 0x760aa27fd048
READ of size 1 at 0x502000005d57 thread T4
    #0 0x61f3f6a99d78 in backend_response /app/pound/src/http.c:3611
    #1 0x61f3f6aa69f7 in do_http /app/pound/src/http.c:4817
    #2 0x61f3f6aa7012 in thr_http /app/pound/src/http.c:4864
    #3 0x760aa3c5b2d5 in asan_thread_start ../../../../src/libsanitizer/asan/asan_interceptors.cpp:234
    #4 0x760aa32a36c1  (/lib/x86_64-linux-gnu/libc.so.6+0x8c6c1) (BuildId: 652dfccae16d17796a09de192ed332fd65dc9abb)
    #5 0x760aa331df6f in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x106f6f) (BuildId: 652dfccae16d17796a09de192ed332fd65dc9abb)

0x502000005d57 is located 5 bytes after 2-byte region [0x502000005d50,0x502000005d52)
allocated by thread T4 here:
    #0 0x760aa3ceede0 in strdup ../../../../src/libsanitizer/asan/asan_interceptors.cpp:578
    #1 0x61f3f6a91808 in http_request_read /app/pound/src/http.c:2692
    #2 0x61f3f6a998e9 in backend_response /app/pound/src/http.c:3596
    #3 0x61f3f6aa69f7 in do_http /app/pound/src/http.c:4817
    #4 0x61f3f6aa7012 in thr_http /app/pound/src/http.c:4864
    #5 0x760aa3c5b2d5 in asan_thread_start ../../../../src/libsanitizer/asan/asan_interceptors.cpp:234

Thread T4 created by T0 here:
    #0 0x760aa3cecbb1 in pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cpp:245
    #1 0x61f3f6ab814b in worker_start /app/pound/src/pound.c:252
    #2 0x61f3f6abbac3 in server /app/pound/src/pound.c:733
    #3 0x61f3f6abe89b in main /app/pound/src/pound.c:1138
    #4 0x760aa3240c89  (/lib/x86_64-linux-gnu/libc.so.6+0x29c89) (BuildId: 652dfccae16d17796a09de192ed332fd65dc9abb)

SUMMARY: AddressSanitizer: heap-buffer-overflow /app/pound/src/http.c:3611 in backend_response
Shadow bytes around the buggy address:
  0x502000005a80: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa
  0x502000005b00: fa fa fd fa fa fa fd fd fa fa 02 fa fa fa 00 03
  0x502000005b80: fa fa fd fd fa fa 00 00 fa fa fd fa fa fa fd fa
  0x502000005c00: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa
  0x502000005c80: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa
=>0x502000005d00: fa fa fd fa fa fa fd fd fa fa[02]fa fa fa fa fa
  0x502000005d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000005e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000005e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000005f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000005f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==11==ABORTING

Pound forwards requests with invalid whitespace around chunk sizes

RFC 9112 defines a chunked message body with the following ABNF rules:

  chunked-body   = *chunk
                   last-chunk
                   trailer-section
                   CRLF

  chunk          = chunk-size [ chunk-ext ] CRLF
                   chunk-data CRLF
  chunk-size     = 1*HEXDIG
  last-chunk     = 1*("0") [ chunk-ext ] CRLF

  chunk-data     = 1*OCTET ; a sequence of chunk-size octets

Note that no whitespace is permitted preceding a chunk-size.
Pound accepts and forwards whitespace before chunk-sizes.

For example, when I send the following invalid request to my Pound reverse proxy:

POST / HTTP/1.1\r\n
Host: whatever\r\n
Transfer-Encoding: chunked\r\n
\r\n
\t0\r\n
\r\n'

here's what it forwards to its backend:

POST / HTTP/1.1\r\n
Host: whatever\r\n
Transfer-Encoding: chunked\r\n
X-Forwarded-For: 172.18.0.1\r\n
X-Forwarded-Proto: http\r\n
X-Forwarded-Port: 80\r\n
\r\n
\t0\r\n
\r\n

Note that the \t before the 0 chunk size is preserved through the proxy.

`ACME "directory"` not working when in `RootJail`

@graygnuorg thank you for keeping this project alive.

I've recently migrated under FreeBSD the from the old aspis version to your new 4.6 release (downloaded and compiled myself).

Wile trying out the ACME functionality, I found that I always get 404 error for the challenge. Doing manual steps to investigate, and found that pound always returns 404 despite a file being placed in the correct directory. Config is like:

User		"nobody"
Group		"nobody"
RootJail	"/var/jail/pound/"
PIDFile		"/var/run/pound.pid"

ListenHTTP
	Address 127.0.0.1
	Port    9080  #access is done through port forwards from WAN to here
	LogLevel 5
	xHTTP 3
	Err404 "/var/jail/pound/err404.txt"
	Err413 "/var/jail/pound/err413.txt"
	Err414 "/var/jail/pound/err414.txt"
	Err500 "/var/jail/pound/err500.txt"
	Err501 "/var/jail/pound/err501.txt"
	Err503 "/var/jail/pound/err503.txt"

	Service
		HeadRequire "Host: someotherhost.example.com"
		Backend
			Address 192.168.1.22
			Port    80
			TimeOut 900
		End
	End

	ACME "/var/jail/pound/acme"

	...

Placed a file under /var/jail/pound/acme (with echo test > /var/jail/pound/acme/aaa.txt) and trying to access through a browser via http://example.com/.well-known/acme-challenge/aaa.txt results in Error404. Also tried to place the file at /var/jail/pound/acme/.well-known/acme-challenge/aaa.txt but still 404.

In the log only:

Mar 28 10:15:34 | pound | 68281 | example.com 192.168.0.1 - - [28/Mar/2023:10:15:34 +0200]  "GET /.well-known/acme-challenge/aaa.txt HTTP/1.1" 404 - "" "Mozilla/5.0  (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0"  ((acme) -> acme:/var/jail/pound/acme/$1) 0.000 sec

Of course if I omit or modify .well-known/acme-challenge from the URL I get Error503 so it looks like the ACME listener properly detects it, but doesn't serve the file.

Commenting out the RootJail configuration seems to fix it. But I don't see why, as the ACME directory is within the jail, and Err files are served well from there.

Small logging patch

Hi Sergey,

Thanks a lot for continuing the pound project, nice to see the story is going on!

May I propose a small patch which slightly changes the logging?

The first changes affect the http_log_1() and http_log_2() where they write the response_code to the log instead of what?
In my logs I never see anything printed after the - so it ends up with simply two spaces. I thought it's better to have the HTTP status code there instead of nothing but I don't know what should be printed there instead.

From
Apr 3 15:12:47 ns1 pound[15656]: 18.143.5.18 GET /mail/ HTTP/1.1 - (abc.invoca.ch/- -> 18.161.91.34:8080) 0.018 sec
To
Apr 3 15:12:47 ns1 pound[15656]: 18.143.5.18 GET /mail/ HTTP/1.1 - 302 (abc.invoca.ch/- -> 18.161.91.34:8080) 0.018 sec

The second change is to bring the terminating thread message in line with other messages about threads:

From
Apr 3 15:12:48 ns1 pound[15656]: (7f404797e700) e503 no service "GET /favicon.ico HTTP/1.1" from 18.143.5.18 abc.invoca.ch
Apr 3 15:12:48 ns1 pound[15656]: thread 7f404797e700 terminating on idle timeout

To
Apr 3 15:12:48 ns1 pound[15656]: (7f404797e700) e503 no service "GET /favicon.ico HTTP/1.1" from 18.143.5.18 abc.invoca.ch
Apr 3 15:12:48 ns1 pound[15656]: (7f404797e700) terminating thread on idle timeout

Thanks,
Simon

pound-4.7-logmsg.patch.txt

Pound forwards messages containing unrecognized transfer codings

Pound forwards unrecognized transfer codings. This is something that the standard recommends against. From RFC 9112, section 6.1:

A server that receives a request message with a transfer coding it does not understand SHOULD respond with 501 (Not Implemented).

While Pound's current behavior is not in violation of the RFCs, it's not particularly wise because some origin servers have strange interpretations of transfer codings. For example, there exist servers that interpret all unrecognized transfer codings as equivalent to chunked. This obviously pairs very poorly with Pound's policy of "forward all unknown transfer codings."

Nearly all other reverse proxies (including Akamai CDN, Apache httpd, Apache Traffic Server, Caddy, H2O, HAProxy, nghttpx, Nginx, Squid, Varnish, AWS CloudFront, Cloudflare CDN, Fastly, Google Cloud classic application load balancer, Google Cloud global application load balancer, and OpenBSD relayd) reject requests containing unrecognized transfer codings.

OpenSSL 3 misses dhparam -C option to print C code

OpenSSL 3 misses dhparam -C option to print C code.

Resulting error:
make -C pound CC="ccache arm-linux-uclibc-gcc" make[1]: Entering directory '/media/egc/linuxdata/ddwrt/src/router/pound' openssl dhparam -5 -C -noout 512 > dh512.h

Code is in Makefile.am

Pound forwards requests with multiple `Transfer-Encoding: chunked` headers

When I send the following request to Pound:

GET / HTTP/1.1\r\n
Host: a\r\n
Transfer-Encoding: chunked\r\n
Transfer-Encoding: chunked\r\n
\r\n
0\r\n
\r\n

It forwards the following to my backend:

GET / HTTP/1.1\r\n
Host: a\r\n
Transfer-Encoding: chunked\r\n
Transfer-Encoding: chunked\r\n
X-Forwarded-For: 172.19.0.1\r\n
X-Forwarded-Proto: http\r\n
X-Forwarded-Port: 80\r\n
\r\n
0\r\n
\r\n

Note that the two Transfer-Encoding headers are preserved. This is problematic for the many servers that misinterpret such requests, and can lead to request smuggling.

There are three potential fixes for this problem:

  1. Reject messages with multiple Transfer-Encoding: chunked headers. This is what Apache, Caddy, Envoy, HAProxy, nghttpx, Nginx, LiteSpeed, Squid, Traefik, Akamai, AWS, Azure, CloudFlare, Fastly, and Google Cloud do.
  2. Normalize the request to have only one Transfer-Encoding: chunked header. This is what Apache Traffic Server does.
  3. Buffer the request and use Content-Length instead. This is what H2O and Varnish do.

Segmentation fault with pound 4.11 on OpenSUSE

I compiled pound 4.11 on some OpenSUSE servers, and installed it.

When running pound and pointing it to the configuration file, it results in: Segmentation fault (core dumped).

This happens already when verifying the configuration file with "-c", example

 /usr/local/sbin/pound -c -f /path/to/my/poundconfiguration.cfg
Segmentation fault (core dumped)

Valgrind gives some details:

==11314== Memcheck, a memory error detector
==11314== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11314== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==11314== Command: /usr/sbin/pound.new -c -f /etc/pound.cfg
==11314==
==11314== Invalid read of size 4
==11314==    at 0x40E7B0: parse_config_file (config.c:5134)
==11314==    by 0x40ECD5: config_parse (config.c:5354)
==11314==    by 0x405813: main (pound.c:1000)
==11314==  Address 0x10 is not stack'd, malloc'd or (recently) free'd
==11314==
==11314==
==11314== Process terminating with default action of signal 11 (SIGSEGV)
==11314==  Access not within mapped region at address 0x10
==11314==    at 0x40E7B0: parse_config_file (config.c:5134)
==11314==    by 0x40ECD5: config_parse (config.c:5354)
==11314==    by 0x405813: main (pound.c:1000)
...
==11314== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

My crystal ball told me that pound expects a configuration file, even if empty, at /usr/local/etc/pound.cfg
Based on that I found a workaround:

sudo mkdir /usr/local/etc
sudo touch /usr/local/etc/pound.cfg

and no more Segmentation fault.

I assume that at installation the file pound.cfg was not created because there was no directory yet at /usr/local/etc.

I suggest to either remove the requirement of having something at /usr/local/etc/pound.cfg or to make sure it is created at make install.

Debian package Reintroducing ?

Hello,

Thanks for the renewal of this nice proxy. Is there any intent to reintroduce in Debian Packaging,
It was removed from testing in 2022:

=========================================================================
[Date: Mon, 10 Oct 2022 17:24:18 -0000] [ftpmaster: Thorsten Alteholz]
Removed the following packages from unstable:

     pound |    3.0.2-1 | source
     pound | 3.0.2-1+b1 | amd64, arm64, armel, armhf, i386, mips64el, mipsel, ppc64el, s390x
Closed bugs: 1020506

------------------- Reason -------------------
ROM; No further development and support from upstream after the end of the year, should not be part of the next Debian stable release
----------------------------------------------

Best Regards

GPF after a short time

Hi, we are running pound 4.6.90 on Oracle Linux 9 compiled with tcmalloc, openSSL 3.01 and MAXBUF=8192.
After a short time we get a lot of general protection fault errors:

Mar 30 17:09:56 pound-98 pound[26221]: (7f9c30143640) Can't read BIO_f_base64
Mar 30 17:09:56 pound-98 kernel: traps: pound[26228] general protection fault ip:7f9c3086532e sp:7f9c3013fb88 error:0 in libtcmalloc.so.4.5.9[7f9c3083e000+28000]

Any ideas on what to check?

[FR] response headers modification

pound has a good and sufficient mechanism to manipulate request headers. Though, sometimes may be needed to change response headers too (it may be needed especially when there is no way to modify backend server behaviour or when in need of removing «improper» headers, if any.

It would be nice to have a possibility to use appropriate directives inside Backend section (e.g. SetResponseHeader "name: value" and DeleteResponseHeader [options] "pattern") – with the same logic as for request headers (include Rewrite conditionals)

Pound forwards chunk sizes prefixed with `0x`, `-`, and `+`

Because Pound parses chunk sizes using strtoll(, , 16), chunk sizes that begin with 0x are erroneously accepted and forwarded. - and + prefixes are also accepted for the same reason, though - is only accepted when the chunk size is 0. This is not permitted in the HTTP RFCs, and can lead to problems for downstream servers because some servers interpret chunk sizes that begin with 0x as equivalent to 0. This can be used for request smuggling against such servers.

Unable to use the same backend for different virtual hosts

Hi, I have an Apache backend which serves multiples sites on the same IP on port 80 but on different virtual hosts via the ServerName directive:

    http://app1.domain.local
    http://app2.domain.local

and so on.
I'm unable to make this configuration work with pound.
I defined the following backends:

  BackEnd "App1"
          Address app1.domain.local
          Port 80
  End
  BackEnd "App2"
          Address app2.domain.local
          Port 80
  End

This is not working because pound talks with the backend using its IP.

Is there any way to handle this kind of configuration?

Kind regards,
A.

Different behaviour (or bug) in URL parsing between Pound 2.8 and 4.12

Hello,
I'm also hitting this problem.

With Pound 2.8 (compiled with libpcre3-dev)
"curl -I https://test.example.com/test" results into...

HTTP/1.1 301 Moved Permanently
Date: Mon, 19 Aug 2024 16:25:57 GMT
Server: Apache
Location: https://test.example.com/test/
Content-Type: text/html; charset=iso-8859-1

Pound 2.8 config:
ListenHTTPS
Address x.x.x.x
Port 443
xHTTP 2
Cert "xxxxxxxxxxxxxxxx"
Disable TLSv1_1
SSLHonorCipherOrder 1
Ciphers "xxxxxxxxxxxxxxxxx"

    Service
        Url "/test"
        HeadRequire "Host:.*test.example.com.*"
            BackEnd
                    Address x.x.x.x
                    Port    80
                    TimeOut 60
            End
            Session
                    Type IP
                    TTL 300
            End
    End

....

With Pound 4.12 (commit d657f05, compiled with libpcre2-dev)
"curl -I https://test.example.com/test" results into...

HTTP/1.1 301 Moved Permanently
Date: Mon, 19 Aug 2024 16:57:14 GMT
Server: Apache
Location: http://test.example.com/test/
Content-Type: text/html; charset=iso-8859-1

Pound 4.12 config:
ListenHTTPS
Address x.x.x.x
Port 443
xHTTP 2
Cert "xxxxxxxxxxxxx"
Disable TLSv1_1
SSLHonorCipherOrder 1
Ciphers "xxxxxxxxxxxxxx"

    Service
        Url "/test"
        Header "Host:.*test.example.com.*"
            BackEnd
                    Address x.x.x.x
                    Port    80
                    TimeOut 60
            End
            Session
                    Type IP
                    TTL 300
            End
    End

....

As you can see the configs are the same... only Header is used instead of deprecated HeadRequire.

The difference between both systems is:
Pound 2.8 is installed on Debian 11 and libpcre3.
Pound 4.12 is installed on Debian 12 and libpcre2.

I've 4 backends that behave wrong with Pound 4.12 but work flawlessly with Pound 2.8... 2 with Apache and 2 with IIS.
All these backends have NO ListenHTTP Redirection.
The only solution to this problem is adding a ListenHTTP Service to simply redirect http to https for these backends.

Originally posted by @johndoe7000 in #8 (comment)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.