Skip to content

Instantly share code, notes, and snippets.

@concatime
Last active April 19, 2018 21:41
Show Gist options
  • Save concatime/36d58b967c7ef7f66e7acee91aea973c to your computer and use it in GitHub Desktop.
Save concatime/36d58b967c7ef7f66e7acee91aea973c to your computer and use it in GitHub Desktop.
ngx_wizard

[DEPRECATED] Take a look at H2O webserver.

NGiИX WIZARD

Features of ngx_wizard:

  • Optimized nginx ;
  • Tweaked settings ;
  • Bleading Edge ;
  • Self Contained Package ;
  • Compiled from scratch ;
  • Based on shared libraries ;
  • LibreSSL as SSL library ;
  • PCRE Jit as RegEx library ;
  • Brotli compression dynamic module ;
  • Atomic & Jemalloc for internal purpose ;
  • Gold linker ;

Simple wizard for compiling nginx from scratch, independently from distros.

This script is provided AS IS & comes with ABSOLUTELY NO WARRANTY.

Instructions

You need to install git, curl, make and gcc (or clang). Then, run this command:

bash <(curl -s https://gist.githubusercontent.com/concatime/36d58b967c7ef7f66e7acee91aea973c/raw/.sh)

And…, that's it!

To install dependencies on Fedora 26 (where curl & make are preinstalled), run:

dnf check-update || sudo dnf upgrade-minimal --assumeyes
sudo dnf install -by gcc git --setopt=install_weak_deps=False
sudo dnf clean all

Source.

Note #0: You could specify which c compiler will be use by typing CC=gcc-X or CC=clang, followed by the command.

Note #1: You may need to configure FireWall/SELinux appropriately for nginx.

About

Why I used shared version of nginx?

  • Inside builded Makefile are really crap. See this as a concrete example.
  • Following the same vibe, nginx makefile requires a c++ compiler for PCRE. I tried --with-pcre-opt=--disable-cpp, in vain.
  • Upgrading parts seamlessly, without recompiling everything.

I may need help to tweak with-cc-opt & with-ld-opt.

This script was even run on Vultr 2.50$ server's edition (Fedora 26) , and worked perfectly.

Enhancements

Bugs

  • Actually, there is a bug between systemd and nginx which requires this hack. Source.

Warnings

Those are warnings I get usnig gcc-7.1.1:

  • FIXED in master, but I'm waiting for a final release
atomic_ops/sysdeps/standard_ao_double_t.h:35:37: warning: ‘-pedantic’ is not an option that controls warnings [-Wpragmas]
 #     pragma GCC diagnostic ignored "-pedantic"
                                     ^~~~~~~~~~~
  CC       asn1/libcrypto_la-a_bitstr.lo
asn1/a_bitstr.c: In function 'i2c_ASN1_BIT_STRING':
asn1/a_bitstr.c:121:2: warning: 'memcpy': specified size between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=]
  memcpy(p, d, len);
  ^~~~~~~~~~~~~~~~~
[…]
Making install in ssl
[…]
  CC       d1_both.lo
d1_both.c: In function 'dtls1_retransmit_message':
d1_both.c:1147:3: warning: 'save_write_sequence' may be used uninitialized in this function [-Wmaybe-uninitialized]
   memcpy(S3I(s)->write_sequence, save_write_sequence,
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       sizeof(S3I(s)->write_sequence));
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[…]
netcat.o: In function `main':
/tmp/tmp.wnEntS1dZt/libressl-2.6.2/apps/nc/netcat.c:441: warning: the use of `mktemp' is dangerous, better use `mkstemp' or `mkdtemp'
../ngx_brotli/src/ngx_http_brotli_filter_module.c:272:9: warning: ‘BrotliEncoderInputBlockSize’ is deprecated [-Wdeprecated-declarations]
         ctx->brotli_ring = BrotliEncoderInputBlockSize(ctx->encoder);
         ^~~
In file included from ../ngx_brotli/src/ngx_http_brotli_filter_module.c:16:0:
../ngx_brotli/deps/brotli/include/brotli/encode.h:220:41: note: declared here
 BROTLI_DEPRECATED BROTLI_ENC_API size_t BrotliEncoderInputBlockSize(
                                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
../ngx_brotli/src/ngx_http_brotli_filter_module.c: In function ‘ngx_http_brotli_filter_create_encoder’:
../ngx_brotli/src/ngx_http_brotli_filter_module.c:427:16: warning: ‘kBrotliMinWindowBits’ is deprecated [-Wdeprecated-declarations]
                && wbits > kBrotliMinWindowBits)
                ^~
In file included from ../ngx_brotli/src/ngx_http_brotli_filter_module.c:16:0:
../ngx_brotli/deps/brotli/include/brotli/encode.h:39:36: note: declared here
 BROTLI_DEPRECATED static const int kBrotliMinWindowBits =
                                    ^~~~~~~~~~~~~~~~~~~~
../ngx_brotli/src/ngx_http_brotli_filter_module.c: In function ‘ngx_http_brotli_filter_add_data’:
../ngx_brotli/src/ngx_http_brotli_filter_module.c:498:5: warning: ‘BrotliEncoderCopyInputToRingBuffer’ is deprecated [-Wdeprecated-declarations]
     BrotliEncoderCopyInputToRingBuffer(ctx->encoder, size, b->pos);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../ngx_brotli/src/ngx_http_brotli_filter_module.c:16:0:
../ngx_brotli/deps/brotli/include/brotli/encode.h:224:39: note: declared here
 BROTLI_DEPRECATED BROTLI_ENC_API void BrotliEncoderCopyInputToRingBuffer(
                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../ngx_brotli/src/ngx_http_brotli_filter_module.c: In function ‘ngx_http_brotli_filter_process’:
../ngx_brotli/src/ngx_http_brotli_filter_module.c:534:5: warning: ‘BrotliEncoderWriteData’ is deprecated [-Wdeprecated-declarations]
     if (!BrotliEncoderWriteData(ctx->encoder, ctx->last, ctx->flush, &size,
     ^~
In file included from ../ngx_brotli/src/ngx_http_brotli_filter_module.c:16:0:
../ngx_brotli/deps/brotli/include/brotli/encode.h:229:46: note: declared here
 BROTLI_DEPRECATED BROTLI_ENC_API BROTLI_BOOL BrotliEncoderWriteData(
                                              ^~~~~~~~~~~~~~~~~~~~~~
../ngx_brotli/src/ngx_http_brotli_filter_module.c: In function ‘ngx_http_brotli_window’:
../ngx_brotli/src/ngx_http_brotli_filter_module.c:903:5: warning: ‘kBrotliMaxWindowBits’ is deprecated [-Wdeprecated-declarations]
     wbits = kBrotliMaxWindowBits;
     ^~~~~
In file included from ../ngx_brotli/src/ngx_http_brotli_filter_module.c:16:0:
../ngx_brotli/deps/brotli/include/brotli/encode.h:41:36: note: declared here
 BROTLI_DEPRECATED static const int kBrotliMaxWindowBits =
                                    ^~~~~~~~~~~~~~~~~~~~
../ngx_brotli/src/ngx_http_brotli_filter_module.c:904:5: warning: ‘kBrotliMinWindowBits’ is deprecated [-Wdeprecated-declarations]
     mbits = kBrotliMinWindowBits;
     ^~~~~
In file included from ../ngx_brotli/src/ngx_http_brotli_filter_module.c:16:0:
../ngx_brotli/deps/brotli/include/brotli/encode.h:39:36: note: declared here
 BROTLI_DEPRECATED static const int kBrotliMinWindowBits =
                                    ^~~~~~~~~~~~~~~~~~~~

Credits

NGINX=1.14.0
LIBRESSL=2.7.2
LIBATOMIC=7.6.4
JEMALLOC=5.0.1
PCRE=8.42
CFLAGS+=-pipe
MAKEFLAGS+=-sj`nproc`
export CFLAGS MAKEFLAGS
# Too lazy ;)
sudo printf 'You should have git, curl, make and a c compiler installed BEFORE running this script!\nWait 5 seconds to continue, otherwise hit CNTRL’C to abort\n'
sleep 5
set -e
pushd /opt
sudo mkdir --parents local
cd $_
sudo mkdir --parents include lib
cd $_
sudo mkdir --parents pkgconfig
for k in pcre atomic_ops atomic_ops_gpl
do sudo ln lib$k.so.1 lib$k.so --symbolic --force
done
sudo ln libpcreposix.so.0 libpcreposix.so --symbolic --force
echo `pwd` | sudo dd status=none of=/etc/ld.so.conf.d/opt.local.lib.conf
popd
pushd $(mktemp --directory)
for k in ftp.pcre.org/pub/pcre/pcre-$PCRE github.com/jemalloc/jemalloc/releases/download/$JEMALLOC/jemalloc-$JEMALLOC
do curl https://$k.tar.bz2 --location --silent | tar xj &
done
# Background processes
wait
pushd pcre-$PCRE
./configure --disable-cpp --disable-static --enable-jit --enable-unicode-properties
make
sudo install -c pcre.h pcreposix.h /opt/local/include
sudo install -c libpcre.pc libpcreposix.pc /opt/local/lib/pkgconfig
cd .libs
sudo install -c libpcreposix.so.0.0.5 /opt/local/lib
sudo install -c libpcre.so.1.2.9 /opt/local/lib
sudo cp --no-dereference --target-directory /opt/local/lib libpcre.so.1 libpcreposix.so.0
popd
pushd jemalloc-$JEMALLOC
./configure --disable-cxx --disable-stats --libdir=/opt/local/lib --includedir=/opt/local/include
sudo make install_lib_shared install_include
sudo install -c jemalloc.pc /opt/local/lib/pkgconfig
popd
sudo rm pcre-$PCRE jemalloc-$JEMALLOC --force --recursive
for k in ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-$LIBRESSL github.com/ivmai/libatomic_ops/releases/download/v$LIBATOMIC/libatomic_ops-$LIBATOMIC nginx.org/download/nginx-$NGINX
do curl https://$k.tar.gz --location --silent | tar xz &
done
wait
pushd libatomic_ops-$LIBATOMIC
./configure --disable-static --enable-shared --libdir=/opt/local/lib --includedir=/opt/local/include
#--disable-docs
#sudo make install
make
sudo install -c pkgconfig/atomic_ops.pc /opt/local/lib/pkgconfig
cd src
rm config.h
find . -name '*.h' | sudo cpio -pd /opt/local/include
cd .libs
sudo install -c libatomic_ops.so.1.1.1 /opt/local/lib
sudo install -c libatomic_ops_gpl.so.1.1.1 /opt/local/lib
sudo cp --no-dereference --target-directory /opt/local/lib libatomic_ops.so.1 libatomic_ops_gpl.so.1
popd
pushd libressl-$LIBRESSL
./configure --disable-static --prefix=`pwd`/die --libdir=/opt/local/lib --includedir=/opt/local/include
sudo make install
popd
sudo rm libatomic_ops-$LIBATOMIC libressl-$LIBRESSL --force --recursive
sudo ldconfig
git clone https://github.com/google/ngx_brotli.git --recursive
pushd nginx-$NGINX
./configure \
--prefix=/opt/nginx \
--pid-path=/run/nginx.pid \
--group=nginx \
--with-compat \
--with-stream \
--with-threads \
--with-file-aio \
--with-libatomic \
--with-http_v2_module \
--with-http_ssl_module \
--with-stream_ssl_module \
--without-http_gzip_module \
--without-select_module \
--without-poll_module \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module \
--add-dynamic-module=../ngx_brotli \
--with-ld-opt='-L/opt/local/lib -ljemalloc -lrt -Wl,-z,relro,-z,now -fuse-ld=gold' \
--with-cc-opt='-I/opt/local/include -pipe -pthread -g -O2 -march=native -fstack-protector-strong -Wno-error -Wp,-D_FORTIFY_SOURCE=2'
sudo make install
popd
sudo rm -fR `pwd`
popd
pushd /opt/nginx/conf
sudo curl https://gist.githubusercontent.com/concatime/36d58b967c7ef7f66e7acee91aea973c/raw/nginx.conf --remote-name
sudo sed -i s/1024/`ulimit -n`/g nginx.conf
popd
pushd /lib/systemd/system
sudo curl https://gist.githubusercontent.com/concatime/36d58b967c7ef7f66e7acee91aea973c/raw/nginx.service --remote-name
popd
sudo groupadd --force --system nginx
sudo systemctl enable nginx
echo '# systemctl (re)start/stop/reload nginx'
echo …done
# Compress responses on-the-fly.
load_module modules/ngx_http_brotli_filter_module.so;
# Serve pre-compressed files.
load_module modules/ngx_http_brotli_static_module.so;
#user nobody;
pcre_jit on;
worker_processes auto;
worker_rlimit_nofile 100000;
events {
worker_connections 1024;
multi_accept on;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
aio threads;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
server_tokens off;
keepalive_timeout 65s;
resolver 127.0.0.1 valid=300s;
resolver_timeout 5s;
#access_log off;
#log_not_found off;
server {
listen 80 deferred;
listen [::]:80 deferred;
server_name _;
location / {
brotli on; # Brotli on the fly
brotli_types text/plain; # + default text/html
brotli_comp_level 4; # https://certsimple.com/blog/nginx-brotli
}
location /ping {
add_header Content-Type text/plain;
return 201 pong;
}
location /status {
return 204;
}
location /static {
brotli_static on;
}
}
}
# ADD THIS WHEN USING HTTPS
#location /.well-known {
# try_files $uri =404;
#}
[Unit]
Description=NGiИX ~ High performance web server
Documentation=https://nginx.org/en/docs
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStart=/opt/nginx/sbin/nginx
ExecStartPre=/opt/nginx/sbin/nginx -t
ExecStartPost=/bin/sleep .01
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
[Install]
WantedBy=multi-user.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment