From 9dc0820f2325271e2f80f7e7d45f878274d1bc28 Mon Sep 17 00:00:00 2001 From: Matthew R Date: Sat, 3 Apr 2021 02:37:14 -0400 Subject: [PATCH] add various scripts --- Asterisk/README.md | 26 +- Dovecot/README.md | 30 +- Dovecot/dovecot.conf | 204 ++++++------- Makefile | 5 + Nginx/README.md | 30 +- .../Server Blocks/auth.libraryofcode.org.conf | 18 +- .../Server Blocks/bin.libraryofcode.org.conf | 30 +- Nginx/Server Blocks/board.ins.conf | 36 +-- .../certapi.libraryofcode.org.conf | 18 +- .../cloud.libraryofcode.org.conf | 4 +- .../Server Blocks/comm.libraryofcode.org.conf | 44 +++ .../confluence.libraryofcode.org.conf | 51 ++++ .../content.libraryofcode.org.conf | 28 ++ Nginx/nginx.conf | 196 ++++++------- Postfix/README.md | 30 +- Postfix/master.conf | 196 ++++++------- scripts/listnginxserverblocks.sh | 27 ++ scripts/nginxfmt.py | 271 ++++++++++++++++++ 18 files changed, 835 insertions(+), 409 deletions(-) create mode 100644 Makefile create mode 100644 Nginx/Server Blocks/comm.libraryofcode.org.conf create mode 100644 Nginx/Server Blocks/confluence.libraryofcode.org.conf create mode 100644 Nginx/Server Blocks/content.libraryofcode.org.conf create mode 100644 scripts/listnginxserverblocks.sh create mode 100644 scripts/nginxfmt.py diff --git a/Asterisk/README.md b/Asterisk/README.md index 87f52f5..11695ef 100644 --- a/Asterisk/README.md +++ b/Asterisk/README.md @@ -1,13 +1,13 @@ -# Asterisk -*PBX - Private Branch Exchange* - -## Accounts -- root -- asterisk - -## Protocols -- PJSIP [5060-UDP] -- PJSIP over TLS [5061-UDP] -- SIP [5160-UDP] -- SIP over TLS [5161-UDP] -- IAX2 [4569-UDP] +# Asterisk +*PBX - Private Branch Exchange* + +## Accounts +- root +- asterisk + +## Protocols +- PJSIP [5060-UDP] +- PJSIP over TLS [5061-UDP] +- SIP [5160-UDP] +- SIP over TLS [5161-UDP] +- IAX2 [4569-UDP] diff --git a/Dovecot/README.md b/Dovecot/README.md index 9c791c2..df435a4 100644 --- a/Dovecot/README.md +++ b/Dovecot/README.md @@ -1,15 +1,15 @@ -# Dovecot -*MDA - Mail Delivery Agent* - -## Accounts -- root -- dovecot -- dovenull -- mail - -## Protocols -- IMAP [143-TCP] -- IMAPS [993-TCP] - -## Locations -- `/etc/dovecot`: Configuration directory +# Dovecot +*MDA - Mail Delivery Agent* + +## Accounts +- root +- dovecot +- dovenull +- mail + +## Protocols +- IMAP [143-TCP] +- IMAPS [993-TCP] + +## Locations +- `/etc/dovecot`: Configuration directory diff --git a/Dovecot/dovecot.conf b/Dovecot/dovecot.conf index 2896659..00cde3c 100644 --- a/Dovecot/dovecot.conf +++ b/Dovecot/dovecot.conf @@ -1,102 +1,102 @@ -## Dovecot configuration file - -# If you're in a hurry, see http://wiki2.dovecot.org/QuickConfiguration - -# "doveconf -n" command gives a clean output of the changed settings. Use it -# instead of copy&pasting files when posting to the Dovecot mailing list. - -# '#' character and everything after it is treated as comments. Extra spaces -# and tabs are ignored. If you want to use either of these explicitly, put the -# value inside quotes, eg.: key = "# char and trailing whitespace " - -# Most (but not all) settings can be overridden by different protocols and/or -# source/destination IPs by placing the settings inside sections, for example: -# protocol imap { }, local 127.0.0.1 { }, remote 10.0.0.0/8 { } - -# Default values are shown for each setting, it's not required to uncomment -# those. These are exceptions to this though: No sections (e.g. namespace {}) -# or plugin settings are added by default, they're listed only as examples. -# Paths are also just examples with the real defaults being based on configure -# options. The paths listed here are for configure --prefix=/usr -# --sysconfdir=/etc --localstatedir=/var - -# Enable installed protocols -!include_try /usr/share/dovecot/protocols.d/*.protocol - -# A comma separated list of IPs or hosts where to listen in for connections. -# "*" listens in all IPv4 interfaces, "::" listens in all IPv6 interfaces. -# If you want to specify non-default ports or anything more complex, -# edit conf.d/master.conf. -#listen = *, :: - -# Base directory where to store runtime data. -#base_dir = /var/run/dovecot/ - -# Name of this instance. In multi-instance setup doveadm and other commands -# can use -i to select which instance is used (an alternative -# to -c ). The instance name is also added to Dovecot processes -# in ps output. -#instance_name = dovecot - -# Greeting message for clients. -#login_greeting = Dovecot ready. - -# Space separated list of trusted network ranges. Connections from these -# IPs are allowed to override their IP addresses and ports (for logging and -# for authentication checks). disable_plaintext_auth is also ignored for -# these networks. Typically you'd specify your IMAP proxy servers here. -#login_trusted_networks = - -# Space separated list of login access check sockets (e.g. tcpwrap) -#login_access_sockets = - -# With proxy_maybe=yes if proxy destination matches any of these IPs, don't do -# proxying. This isn't necessary normally, but may be useful if the destination -# IP is e.g. a load balancer's IP. -#auth_proxy_self = - -# Show more verbose process titles (in ps). Currently shows user name and -# IP address. Useful for seeing who are actually using the IMAP processes -# (eg. shared mailboxes or if same uid is used for multiple accounts). -#verbose_proctitle = no - -# Should all processes be killed when Dovecot master process shuts down. -# Setting this to "no" means that Dovecot can be upgraded without -# forcing existing client connections to close (although that could also be -# a problem if the upgrade is e.g. because of a security fix). -#shutdown_clients = yes - -# If non-zero, run mail commands via this many connections to doveadm server, -# instead of running them directly in the same process. -#doveadm_worker_count = 0 -# UNIX socket or host:port used for connecting to doveadm server -#doveadm_socket_path = doveadm-server - -# Space separated list of environment variables that are preserved on Dovecot -# startup and passed down to all of its child processes. You can also give -# key=value pairs to always set specific settings. -#import_environment = TZ - -## -## Dictionary server settings -## - -# Dictionary can be used to store key=value lists. This is used by several -# plugins. The dictionary can be accessed either directly or though a -# dictionary server. The following dict block maps dictionary names to URIs -# when the server is used. These can then be referenced using URIs in format -# "proxy::". - -dict { - #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext - #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext -} - -# Most of the actual configuration gets included below. The filenames are -# first sorted by their ASCII value and parsed in that order. The 00-prefixes -# in filenames are intended to make it easier to understand the ordering. -!include conf.d/*.conf - -# A config file can also tried to be included without giving an error if -# it's not found: -!include_try local.conf +## Dovecot configuration file + +# If you're in a hurry, see http://wiki2.dovecot.org/QuickConfiguration + +# "doveconf -n" command gives a clean output of the changed settings. Use it +# instead of copy&pasting files when posting to the Dovecot mailing list. + +# '#' character and everything after it is treated as comments. Extra spaces +# and tabs are ignored. If you want to use either of these explicitly, put the +# value inside quotes, eg.: key = "# char and trailing whitespace " + +# Most (but not all) settings can be overridden by different protocols and/or +# source/destination IPs by placing the settings inside sections, for example: +# protocol imap { }, local 127.0.0.1 { }, remote 10.0.0.0/8 { } + +# Default values are shown for each setting, it's not required to uncomment +# those. These are exceptions to this though: No sections (e.g. namespace {}) +# or plugin settings are added by default, they're listed only as examples. +# Paths are also just examples with the real defaults being based on configure +# options. The paths listed here are for configure --prefix=/usr +# --sysconfdir=/etc --localstatedir=/var + +# Enable installed protocols +!include_try /usr/share/dovecot/protocols.d/*.protocol + +# A comma separated list of IPs or hosts where to listen in for connections. +# "*" listens in all IPv4 interfaces, "::" listens in all IPv6 interfaces. +# If you want to specify non-default ports or anything more complex, +# edit conf.d/master.conf. +#listen = *, :: + +# Base directory where to store runtime data. +#base_dir = /var/run/dovecot/ + +# Name of this instance. In multi-instance setup doveadm and other commands +# can use -i to select which instance is used (an alternative +# to -c ). The instance name is also added to Dovecot processes +# in ps output. +#instance_name = dovecot + +# Greeting message for clients. +#login_greeting = Dovecot ready. + +# Space separated list of trusted network ranges. Connections from these +# IPs are allowed to override their IP addresses and ports (for logging and +# for authentication checks). disable_plaintext_auth is also ignored for +# these networks. Typically you'd specify your IMAP proxy servers here. +#login_trusted_networks = + +# Space separated list of login access check sockets (e.g. tcpwrap) +#login_access_sockets = + +# With proxy_maybe=yes if proxy destination matches any of these IPs, don't do +# proxying. This isn't necessary normally, but may be useful if the destination +# IP is e.g. a load balancer's IP. +#auth_proxy_self = + +# Show more verbose process titles (in ps). Currently shows user name and +# IP address. Useful for seeing who are actually using the IMAP processes +# (eg. shared mailboxes or if same uid is used for multiple accounts). +#verbose_proctitle = no + +# Should all processes be killed when Dovecot master process shuts down. +# Setting this to "no" means that Dovecot can be upgraded without +# forcing existing client connections to close (although that could also be +# a problem if the upgrade is e.g. because of a security fix). +#shutdown_clients = yes + +# If non-zero, run mail commands via this many connections to doveadm server, +# instead of running them directly in the same process. +#doveadm_worker_count = 0 +# UNIX socket or host:port used for connecting to doveadm server +#doveadm_socket_path = doveadm-server + +# Space separated list of environment variables that are preserved on Dovecot +# startup and passed down to all of its child processes. You can also give +# key=value pairs to always set specific settings. +#import_environment = TZ + +## +## Dictionary server settings +## + +# Dictionary can be used to store key=value lists. This is used by several +# plugins. The dictionary can be accessed either directly or though a +# dictionary server. The following dict block maps dictionary names to URIs +# when the server is used. These can then be referenced using URIs in format +# "proxy::". + +dict { + #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext + #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext +} + +# Most of the actual configuration gets included below. The filenames are +# first sorted by their ASCII value and parsed in that order. The 00-prefixes +# in filenames are intended to make it easier to understand the ordering. +!include conf.d/*.conf + +# A config file can also tried to be included without giving an error if +# it's not found: +!include_try local.conf diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f5546f2 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +nginx_server_blocks := $(shell ./scripts/listnginxserverblocks.sh) + +# Formats Nginx configuration files +nginxfmt: + ./scripts/nginxfmt.py ${nginx_server_blocks} diff --git a/Nginx/README.md b/Nginx/README.md index 28a061d..880386d 100644 --- a/Nginx/README.md +++ b/Nginx/README.md @@ -1,15 +1,15 @@ -# Nginx -*HTTP/SMTP/IMAP/POP3 Proxy Server* - -## Accounts -- root -- www-data - -## Protocols -- HTTP [80-TCP] -- HTTPS [443-TCP] - -## Locations -- `/etc/nginx` - Configuration directory - - +# Nginx +*HTTP/SMTP/IMAP/POP3 Proxy Server* + +## Accounts +- root +- www-data + +## Protocols +- HTTP [80-TCP] +- HTTPS [443-TCP] + +## Locations +- `/etc/nginx` - Configuration directory + + diff --git a/Nginx/Server Blocks/auth.libraryofcode.org.conf b/Nginx/Server Blocks/auth.libraryofcode.org.conf index a652130..2206f0c 100644 --- a/Nginx/Server Blocks/auth.libraryofcode.org.conf +++ b/Nginx/Server Blocks/auth.libraryofcode.org.conf @@ -18,21 +18,21 @@ server { location / { - proxy_set_header Host $host; + proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Frame-Options SAMEORIGIN; + proxy_set_header X-Frame-Options SAMEORIGIN; - proxy_pass http://localhost:8200; + proxy_pass http://localhost:8200; - proxy_read_timeout 90; + proxy_read_timeout 90; - proxy_redirect http://localhost:8200 https://auth.libraryofcode.org; + proxy_redirect http://localhost:8200 https://auth.libraryofcode.org; - } + } } diff --git a/Nginx/Server Blocks/bin.libraryofcode.org.conf b/Nginx/Server Blocks/bin.libraryofcode.org.conf index d0228c0..82ca340 100644 --- a/Nginx/Server Blocks/bin.libraryofcode.org.conf +++ b/Nginx/Server Blocks/bin.libraryofcode.org.conf @@ -1,23 +1,23 @@ server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name bin.libraryofcode.org; + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name bin.libraryofcode.org; - ssl_certificate /etc/nginx/ssl/org.chain.crt; - ssl_certificate_key /etc/nginx/ssl/org.key.pem; + ssl_certificate /etc/nginx/ssl/org.chain.crt; + ssl_certificate_key /etc/nginx/ssl/org.key.pem; - ssl_session_cache builtin:1000 shared:SSL:10m; - ssl_protocols TLSv1.2; + ssl_session_cache builtin:1000 shared:SSL:10m; + ssl_protocols TLSv1.2; - ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; - ssl_prefer_server_ciphers on; + ssl_prefer_server_ciphers on; - ssl_stapling on; - ssl_stapling_verify on; + ssl_stapling on; + ssl_stapling_verify on; - root /var/binary; - location / { - autoindex on; - } + root /var/binary; + location / { + autoindex on; + } } diff --git a/Nginx/Server Blocks/board.ins.conf b/Nginx/Server Blocks/board.ins.conf index b23e5de..ebc1a33 100644 --- a/Nginx/Server Blocks/board.ins.conf +++ b/Nginx/Server Blocks/board.ins.conf @@ -24,41 +24,41 @@ server { #limit_req zone=one burst=15; location / { - proxy_set_header Host $host; + proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Frame-Options SAMEORIGIN; + proxy_set_header X-Frame-Options SAMEORIGIN; - proxy_pass http://localhost:3121; + proxy_pass http://localhost:3121; - proxy_read_timeout 90; + proxy_read_timeout 90; - proxy_redirect http://localhost:3121 https://board.ins; + proxy_redirect http://localhost:3121 https://board.ins; - } + } location /api { - proxy_set_header Host $host; + proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Frame-Options SAMEORIGIN; + proxy_set_header X-Frame-Options SAMEORIGIN; - proxy_pass http://localhost:3892; + proxy_pass http://localhost:3892; - proxy_read_timeout 90; + proxy_read_timeout 90; - proxy_redirect http://localhost:3892 https://board.ins/api; + proxy_redirect http://localhost:3892 https://board.ins/api; - } + } } diff --git a/Nginx/Server Blocks/certapi.libraryofcode.org.conf b/Nginx/Server Blocks/certapi.libraryofcode.org.conf index 95bbeed..3eda767 100644 --- a/Nginx/Server Blocks/certapi.libraryofcode.org.conf +++ b/Nginx/Server Blocks/certapi.libraryofcode.org.conf @@ -24,21 +24,21 @@ server { #limit_req zone=one burst=15; location / { - proxy_set_header Host $host; + proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Frame-Options SAMEORIGIN; + proxy_set_header X-Frame-Options SAMEORIGIN; - proxy_pass http://localhost:3030; + proxy_pass http://localhost:3030; - proxy_read_timeout 90; + proxy_read_timeout 90; - proxy_redirect http://localhost:3030 https://certapi.libraryofcode.org; + proxy_redirect http://localhost:3030 https://certapi.libraryofcode.org; - } + } } diff --git a/Nginx/Server Blocks/cloud.libraryofcode.org.conf b/Nginx/Server Blocks/cloud.libraryofcode.org.conf index 0794de5..259e5ac 100644 --- a/Nginx/Server Blocks/cloud.libraryofcode.org.conf +++ b/Nginx/Server Blocks/cloud.libraryofcode.org.conf @@ -25,9 +25,9 @@ server { location / { - return 307 $scheme://www.libraryofcode.org/; + return 307 $scheme://www.libraryofcode.org/; } location ~ /(.*)$ { - rewrite https://$1.cloud.libraryofcode.org temporary; + rewrite https://$1.cloud.libraryofcode.org temporary; } } diff --git a/Nginx/Server Blocks/comm.libraryofcode.org.conf b/Nginx/Server Blocks/comm.libraryofcode.org.conf new file mode 100644 index 0000000..c6cb42e --- /dev/null +++ b/Nginx/Server Blocks/comm.libraryofcode.org.conf @@ -0,0 +1,44 @@ +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name comm.libraryofcode.org; + + ssl_certificate /etc/nginx/ssl/org.chain.crt; + ssl_certificate_key /etc/nginx/ssl/org.key.pem; + + ssl_session_cache builtin:1000 shared:SSL:10m; + #include /etc/nginx/error/502; + #include /etc/nginx/error/504; + #include /etc/nginx/error/500; + #include /etc/nginx/error/404; + #include /etc/nginx/error/429; + ssl_protocols TLSv1.2; + + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + + ssl_prefer_server_ciphers on; + + ssl_stapling on; + ssl_stapling_verify on; + + #limit_req zone=one burst=15; + location / { + + proxy_set_header Host $host; + + proxy_set_header X-Real-IP $remote_addr; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_set_header X-Frame-Options SAMEORIGIN; + + proxy_pass http://localhost:3895; + + proxy_read_timeout 90; + + proxy_redirect http://localhost:3895 https://comm.libraryofcode.org; + + } +} diff --git a/Nginx/Server Blocks/confluence.libraryofcode.org.conf b/Nginx/Server Blocks/confluence.libraryofcode.org.conf new file mode 100644 index 0000000..a4fdbeb --- /dev/null +++ b/Nginx/Server Blocks/confluence.libraryofcode.org.conf @@ -0,0 +1,51 @@ +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name confluence.libraryofcode.org; + + ssl_certificate /etc/nginx/ssl/org.chain.crt; + ssl_certificate_key /etc/nginx/ssl/org.key.pem; + + ssl_session_cache builtin:1000 shared:SSL:10m; + #include /etc/nginx/error/502; + #include /etc/nginx/error/504; + #include /etc/nginx/error/500; + #include /etc/nginx/error/404; + #include /etc/nginx/error/429; + ssl_protocols TLSv1.2; + + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + + ssl_prefer_server_ciphers on; + + ssl_stapling on; + ssl_stapling_verify on; + + #limit_req zone=one burst=15; + location / { + + proxy_set_header Host $host; + + proxy_set_header X-Real-IP $remote_addr; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header X-Forwarded-Proto $scheme; + + proxy_pass http://localhost:3022; + + proxy_read_timeout 90; + + proxy_redirect http://localhost:3022 https://confluence.libraryofcode.org; + + } + location /synchrony { + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Server $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_pass http://localhost:8091/synchrony; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + } +} diff --git a/Nginx/Server Blocks/content.libraryofcode.org.conf b/Nginx/Server Blocks/content.libraryofcode.org.conf new file mode 100644 index 0000000..b78f26d --- /dev/null +++ b/Nginx/Server Blocks/content.libraryofcode.org.conf @@ -0,0 +1,28 @@ +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name content.libraryofcode.org; + + ssl_certificate /etc/nginx/ssl/org.chain.crt; + ssl_certificate_key /etc/nginx/ssl/org.key.pem; + + ssl_session_cache builtin:1000 shared:SSL:10m; + ssl_protocols TLSv1.2; + + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + + ssl_prefer_server_ciphers on; + + ssl_stapling on; + ssl_stapling_verify on; + + root /var/www/content; + location / { + autoindex on; + } + location /sec { + autoindex on; + auth_basic "Secure Area"; + auth_basic_user_file /etc/nginx/htpasswd; + } +} diff --git a/Nginx/nginx.conf b/Nginx/nginx.conf index f07f1ac..91d6218 100644 --- a/Nginx/nginx.conf +++ b/Nginx/nginx.conf @@ -1,98 +1,98 @@ -# Main Nginx Configuration File - -user www-data; -worker_processes auto; -pid /run/nginx.pid; -include /etc/nginx/modules-enabled/*.conf; - -events { - worker_connections 768; - # multi_accept on; -} - -http { - - ## - # Basic Settings - ## - - sendfile on; - tcp_nopush on; - tcp_nodelay on; - keepalive_timeout 65; - types_hash_max_size 2048; - server_tokens off; - more_set_headers 'Server: Library of Code Staff Command (https://www.libraryofcode.org)'; - add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; - - # server_names_hash_bucket_size 64; - # server_name_in_redirect off; - - include /etc/nginx/mime.types; - default_type application/octet-stream; - - ## - # SSL Settings - ## - - ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE - ssl_prefer_server_ciphers on;ssl_session_cache shared:SSL:10m; - ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; - ssl_dhparam /etc/nginx/dhparam.pem - ;ssl_ecdh_curve secp384r1; - - ## - # Logging Settings - ## - - #access_log /var/log/nginx/access.log; - #error_log /var/log/nginx/error.log; - - - log_format main_ext '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '"$host" sn="$server_name" ' 'rt=$request_time ' 'ua="$upstream_addr" us="$upstream_status" ' 'ut="$upstream_response_time" ul="$upstream_response_length" ' 'cs=$upstream_cache_status' ; - - access_log /var/log/nginx/access.log main_ext; - error_log /var/log/nginx/error.log warn; - ## - # Gzip Settings - ## - - gzip on; - gzip_disable "msie6"; - - # gzip_vary on; - # gzip_proxied any; - # gzip_comp_level 6; - # gzip_buffers 16 8k; - # gzip_http_version 1.1; - # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; - - ## - # Virtual Host Configs - ## - - include /etc/nginx/conf.d/*.conf; - include /etc/nginx/sites-enabled/*; -} - - -#mail { -# # See sample authentication script at: -# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript -# -# # auth_http localhost/auth.php; -# # pop3_capabilities "TOP" "USER"; -# # imap_capabilities "IMAP4rev1" "UIDPLUS"; -# -# server { -# listen localhost:110; -# protocol pop3; -# proxy on; -# } -# -# server { -# listen localhost:143; -# protocol imap; -# proxy on; -# } -#} +# Main Nginx Configuration File + +user www-data; +worker_processes auto; +pid /run/nginx.pid; +include /etc/nginx/modules-enabled/*.conf; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + + ## + # Basic Settings + ## + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + server_tokens off; + more_set_headers 'Server: Library of Code Staff Command (https://www.libraryofcode.org)'; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; + + # server_names_hash_bucket_size 64; + # server_name_in_redirect off; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + ## + # SSL Settings + ## + + ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE + ssl_prefer_server_ciphers on;ssl_session_cache shared:SSL:10m; + ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; + ssl_dhparam /etc/nginx/dhparam.pem + ;ssl_ecdh_curve secp384r1; + + ## + # Logging Settings + ## + + #access_log /var/log/nginx/access.log; + #error_log /var/log/nginx/error.log; + + + log_format main_ext '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '"$host" sn="$server_name" ' 'rt=$request_time ' 'ua="$upstream_addr" us="$upstream_status" ' 'ut="$upstream_response_time" ul="$upstream_response_length" ' 'cs=$upstream_cache_status' ; + + access_log /var/log/nginx/access.log main_ext; + error_log /var/log/nginx/error.log warn; + ## + # Gzip Settings + ## + + gzip on; + gzip_disable "msie6"; + + # gzip_vary on; + # gzip_proxied any; + # gzip_comp_level 6; + # gzip_buffers 16 8k; + # gzip_http_version 1.1; + # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + ## + # Virtual Host Configs + ## + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} + + +#mail { +# # See sample authentication script at: +# # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript +# +# # auth_http localhost/auth.php; +# # pop3_capabilities "TOP" "USER"; +# # imap_capabilities "IMAP4rev1" "UIDPLUS"; +# +# server { +# listen localhost:110; +# protocol pop3; +# proxy on; +# } +# +# server { +# listen localhost:143; +# protocol imap; +# proxy on; +# } +#} diff --git a/Postfix/README.md b/Postfix/README.md index a1dc523..a707f99 100644 --- a/Postfix/README.md +++ b/Postfix/README.md @@ -1,15 +1,15 @@ -# Postfix -*MTA - Mail Transfer Agent* - -## Accounts -- root -- postfix - -## Protocols -- SMTP (MTA <-> MTA) [25-TCP] -- SMTP (MUA <-> MTA) [587-TCP] -- SMTPS (MUA <-> MTA) [467-TCP] - -## Locations -- `/etc/postfix` - Configuration directory - +# Postfix +*MTA - Mail Transfer Agent* + +## Accounts +- root +- postfix + +## Protocols +- SMTP (MTA <-> MTA) [25-TCP] +- SMTP (MUA <-> MTA) [587-TCP] +- SMTPS (MUA <-> MTA) [467-TCP] + +## Locations +- `/etc/postfix` - Configuration directory + diff --git a/Postfix/master.conf b/Postfix/master.conf index 2fcb010..7864480 100644 --- a/Postfix/master.conf +++ b/Postfix/master.conf @@ -1,98 +1,98 @@ -# See /usr/share/postfix/main.cf.dist for a commented, more complete version - - -# Debian specific: Specifying a file name will cause the first -# line of that file to be used as the name. The Debian default -# is /etc/mailname. -#myorigin = /etc/mailname - -smtpd_banner = $myhostname Library of Code sp-us Staff Services | ESMTP (Debian/GNU) -biff = no - -# appending .domain is the MUA's job. -append_dot_mydomain = no - -# Uncomment the next line to generate "delayed mail" warnings -#delay_warning_time = 4h - -readme_directory = no - -# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on -# fresh installs. -compatibility_level = 2 - -# TLS parameters -smtpd_tls_cert_file=/etc/postfix/ssl/globalsign.crt -smtpd_tls_key_file=/etc/postfix/ssl/globalsign.key.pem -smtpd_use_tls=yes -smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache -smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache -smtp_tls_security_level = may -smtpd_tls_security_level = may -smtp_tls_note_starttls_offer = yes -smtpd_tls_CAfile = /etc/postfix/ssl/globalsign.ca.crt -smtpd_tls_loglevel = 1 -smtpd_tls_received_header = yes -smtpd_tls_session_cache_timeout = 3600s -tls_random_source = dev:/dev/urandom - -# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for -# information on enabling SSL in the smtp client. - -# RESTRICTIONS -smtpd_relay_restrictions = - permit_mynetworks, - permit_sasl_authenticated, - defer_unauth_destination, -smtpd_helo_restrictions = - permit_mynetworks, - reject_non_fqdn_helo_hostname, - reject_invalid_helo_hostname, - reject_unknown_helo_hostname, - permit, -smtpd_sender_restrictions = - reject_unknown_sender_domain, - reject_unknown_reverse_client_hostname, - reject_unknown_client_hostname, - reject_sender_login_mismatch, - permit_mynetworks, - permit_sasl_authenticated, - permit, -smtpd_recipient_restrictions = - reject_unauth_pipelining, - reject_non_fqdn_recipient, - reject_unknown_recipient_domain, - permit_mynetworks, - check_policy_service inet:127.0.0.1:10023 - permit, - -myhostname = staff.libraryofcode.org -alias_maps = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases -alias_database = hash:/etc/aliases -smtpd_sender_login_maps = hash:/etc/postfix/virtual-mailbox-users - -myorigin = /etc/mailname -mydestination = $myhostname, libraryofcode.org, libraryofcode.us staff.libraryofcode.us, staff-libraryofcode.staff.libraryofcode.us, localhost.staff.libraryofcode.us, localhost, libraryofcode.us -relayhost = -relay_domains = lists.libraryofcode.org -mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 63.141.252.130 -mailbox_size_limit = 0 -mailbox_command = procmail -a "$EXTENSION" DEFAULT=/var/mail/$USER -recipient_delimiter = + -inet_interfaces = all -inet_protocols = all -smtpd_sasl_auth_enable = yes -broken_sasl_auth_clients = yes -milter_default_action = accept -milter_protocol = 6 -smtpd_milters = inet:localhost:8891, local:/opendmarc/opendmarc.sock -non_smtpd_milters = $smtpd_milters -mail_name = Library of Code sp-us | Staff Command -virtual_alias_maps = hash:/etc/postfix/virtual - -#authorized_submit_users = !boss, !test, static:all -message_size_limit = 1073741824 -transport_maps = hash:/etc/postfix/transport -unknown_local_recipient_reject_code = 550 -mailman_destination_recipient_limit = 1 -#local_recipient_maps = hash:/var/lib/mailman3/data/postfix_lmtp +# See /usr/share/postfix/main.cf.dist for a commented, more complete version + + +# Debian specific: Specifying a file name will cause the first +# line of that file to be used as the name. The Debian default +# is /etc/mailname. +#myorigin = /etc/mailname + +smtpd_banner = $myhostname Library of Code sp-us Staff Services | ESMTP (Debian/GNU) +biff = no + +# appending .domain is the MUA's job. +append_dot_mydomain = no + +# Uncomment the next line to generate "delayed mail" warnings +#delay_warning_time = 4h + +readme_directory = no + +# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on +# fresh installs. +compatibility_level = 2 + +# TLS parameters +smtpd_tls_cert_file=/etc/postfix/ssl/globalsign.crt +smtpd_tls_key_file=/etc/postfix/ssl/globalsign.key.pem +smtpd_use_tls=yes +smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache +smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache +smtp_tls_security_level = may +smtpd_tls_security_level = may +smtp_tls_note_starttls_offer = yes +smtpd_tls_CAfile = /etc/postfix/ssl/globalsign.ca.crt +smtpd_tls_loglevel = 1 +smtpd_tls_received_header = yes +smtpd_tls_session_cache_timeout = 3600s +tls_random_source = dev:/dev/urandom + +# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for +# information on enabling SSL in the smtp client. + +# RESTRICTIONS +smtpd_relay_restrictions = + permit_mynetworks, + permit_sasl_authenticated, + defer_unauth_destination, +smtpd_helo_restrictions = + permit_mynetworks, + reject_non_fqdn_helo_hostname, + reject_invalid_helo_hostname, + reject_unknown_helo_hostname, + permit, +smtpd_sender_restrictions = + reject_unknown_sender_domain, + reject_unknown_reverse_client_hostname, + reject_unknown_client_hostname, + reject_sender_login_mismatch, + permit_mynetworks, + permit_sasl_authenticated, + permit, +smtpd_recipient_restrictions = + reject_unauth_pipelining, + reject_non_fqdn_recipient, + reject_unknown_recipient_domain, + permit_mynetworks, + check_policy_service inet:127.0.0.1:10023 + permit, + +myhostname = staff.libraryofcode.org +alias_maps = hash:/etc/aliases, hash:/var/lib/mailman/data/aliases +alias_database = hash:/etc/aliases +smtpd_sender_login_maps = hash:/etc/postfix/virtual-mailbox-users + +myorigin = /etc/mailname +mydestination = $myhostname, libraryofcode.org, libraryofcode.us staff.libraryofcode.us, staff-libraryofcode.staff.libraryofcode.us, localhost.staff.libraryofcode.us, localhost, libraryofcode.us +relayhost = +relay_domains = lists.libraryofcode.org +mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 63.141.252.130 +mailbox_size_limit = 0 +mailbox_command = procmail -a "$EXTENSION" DEFAULT=/var/mail/$USER +recipient_delimiter = + +inet_interfaces = all +inet_protocols = all +smtpd_sasl_auth_enable = yes +broken_sasl_auth_clients = yes +milter_default_action = accept +milter_protocol = 6 +smtpd_milters = inet:localhost:8891, local:/opendmarc/opendmarc.sock +non_smtpd_milters = $smtpd_milters +mail_name = Library of Code sp-us | Staff Command +virtual_alias_maps = hash:/etc/postfix/virtual + +#authorized_submit_users = !boss, !test, static:all +message_size_limit = 1073741824 +transport_maps = hash:/etc/postfix/transport +unknown_local_recipient_reject_code = 550 +mailman_destination_recipient_limit = 1 +#local_recipient_maps = hash:/var/lib/mailman3/data/postfix_lmtp diff --git a/scripts/listnginxserverblocks.sh b/scripts/listnginxserverblocks.sh new file mode 100644 index 0000000..bfe8d01 --- /dev/null +++ b/scripts/listnginxserverblocks.sh @@ -0,0 +1,27 @@ +#This is free and unencumbered software released into the public domain. + +#Anyone is free to copy, modify, publish, use, compile, sell, or +#distribute this software, either in source code form or as a compiled +#binary, for any purpose, commercial or non-commercial, and by any +#means. + +#In jurisdictions that recognize copyright laws, the author or authors +#of this software dedicate any and all copyright interest in the +#software to the public domain. We make this dedication for the benefit +#of the public at large and to the detriment of our heirs and +#successors. We intend this dedication to be an overt act of +#relinquishment in perpetuity of all present and future rights to this +#software under copyright law. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +#EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +#MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +#IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +#OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +#ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +#OTHER DEALINGS IN THE SOFTWARE. + +#For more information, please refer to + + +find "Nginx/Server Blocks" -type f -name "*" | awk '{ print "\""$0"\""}' diff --git a/scripts/nginxfmt.py b/scripts/nginxfmt.py new file mode 100644 index 0000000..160a578 --- /dev/null +++ b/scripts/nginxfmt.py @@ -0,0 +1,271 @@ +#!/usr/bin/env python3 + +""" + Copyright 2016 Michał Słomkowski + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +""" + +"""This Python script formats nginx configuration files in consistent way. +Originally published under https://github.com/1connect/nginx-config-formatter +""" + +import argparse +import codecs + +import re + +__author__ = "Michał Słomkowski" +__license__ = "Apache 2.0" +__version__ = "1.0.2" + +INDENTATION = ' ' * 4 + +TEMPLATE_VARIABLE_OPENING_TAG = '___TEMPLATE_VARIABLE_OPENING_TAG___' +TEMPLATE_VARIABLE_CLOSING_TAG = '___TEMPLATE_VARIABLE_CLOSING_TAG___' + +TEMPLATE_BRACKET_OPENING_TAG = '___TEMPLATE_BRACKET_OPENING_TAG___' +TEMPLATE_BRACKET_CLOSING_TAG = '___TEMPLATE_BRACKET_CLOSING_TAG___' + + +def strip_line(single_line): + """Strips the line and replaces neighbouring whitespaces with single space (except when within quotation marks).""" + single_line = single_line.strip() + if single_line.startswith('#'): + return single_line + + within_quotes = False + parts = [] + for part in re.split('"', single_line): + if within_quotes: + parts.append(part) + else: + parts.append(re.sub(r'[\s]+', ' ', part)) + within_quotes = not within_quotes + return '"'.join(parts) + + +def count_multi_semicolon(single_line): + """count multi_semicolon (except when within quotation marks).""" + single_line = single_line.strip() + if single_line.startswith('#'): + return 0, 0 + + within_quotes = False + q = 0 + c = 0 + for part in re.split('"', single_line): + if within_quotes: + q = 1 + else: + c += part.count(';') + within_quotes = not within_quotes + return q, c + + +def multi_semicolon(single_line): + """break multi_semicolon into multiline (except when within quotation marks).""" + single_line = single_line.strip() + if single_line.startswith('#'): + return single_line + + within_quotes = False + parts = [] + for part in re.split('"', single_line): + if within_quotes: + parts.append(part) + else: + parts.append(part.replace(";", ";\n")) + within_quotes = not within_quotes + return '"'.join(parts) + + +def apply_variable_template_tags(line: str) -> str: + """Replaces variable indicators ${ and } with tags, so subsequent formatting is easier.""" + return re.sub(r'\${\s*(\w+)\s*}', + TEMPLATE_VARIABLE_OPENING_TAG + r"\1" + TEMPLATE_VARIABLE_CLOSING_TAG, + line, + flags=re.UNICODE) + + +def strip_variable_template_tags(line: str) -> str: + """Replaces tags back with ${ and } respectively.""" + return re.sub(TEMPLATE_VARIABLE_OPENING_TAG + r'\s*(\w+)\s*' + TEMPLATE_VARIABLE_CLOSING_TAG, + r'${\1}', + line, + flags=re.UNICODE) + + +def apply_bracket_template_tags(content: str) -> str: + """ Replaces bracket { and } with tags, so subsequent formatting is easier.""" + result = "" + in_quotes = False + last_c = "" + + for c in content: + if (c == "\'" or c == "\"") and last_c != "\\": + in_quotes = reverse_in_quotes_status(in_quotes) + if in_quotes: + if c == "{": + result += TEMPLATE_BRACKET_OPENING_TAG + elif c == "}": + result += TEMPLATE_BRACKET_CLOSING_TAG + else: + result += c + else: + result += c + last_c = c + return result + + +def reverse_in_quotes_status(status: bool) -> bool: + if status: + return False + return True + + +def strip_bracket_template_tags(content: str) -> str: + """ Replaces tags back with { and } respectively.""" + content = content.replace(TEMPLATE_BRACKET_OPENING_TAG, "{", -1) + content = content.replace(TEMPLATE_BRACKET_CLOSING_TAG, "}", -1) + return content + + +def clean_lines(orig_lines) -> list: + """Strips the lines and splits them if they contain curly brackets.""" + cleaned_lines = [] + for line in orig_lines: + line = strip_line(line) + line = apply_variable_template_tags(line) + if line == "": + cleaned_lines.append("") + continue + else: + if line.startswith("#"): + cleaned_lines.append(strip_variable_template_tags(line)) + else: + q, c = count_multi_semicolon(line) + if q == 1 and c > 1: + ml = multi_semicolon(line) + cleaned_lines.extend(clean_lines(ml.splitlines())) + elif q != 1 and c > 1: + newlines = line.split(";") + cleaned_lines.extend(clean_lines(["".join([ln, ";"]) for ln in newlines if ln != ""])) + else: + if line.startswith("rewrite"): + cleaned_lines.append(strip_variable_template_tags(line)) + else: + cleaned_lines.extend( + [strip_variable_template_tags(l).strip() for l in re.split(r"([{}])", line) if l != ""]) + return cleaned_lines + + +def join_opening_bracket(lines): + """When opening curly bracket is in it's own line (K&R convention), it's joined with precluding line (Java).""" + modified_lines = [] + for i in range(len(lines)): + if i > 0 and lines[i] == "{": + modified_lines[-1] += " {" + else: + modified_lines.append(lines[i]) + return modified_lines + + +def perform_indentation(lines): + """Indents the lines according to their nesting level determined by curly brackets.""" + indented_lines = [] + current_indent = 0 + for line in lines: + if not line.startswith("#") and line.endswith('}') and current_indent > 0: + current_indent -= 1 + + if line != "": + indented_lines.append(current_indent * INDENTATION + line) + else: + indented_lines.append("") + + if not line.startswith("#") and line.endswith('{'): + current_indent += 1 + + return indented_lines + + +def format_config_contents(contents): + """Accepts the string containing nginx configuration and returns formatted one. Adds newline at the end.""" + contents = apply_bracket_template_tags(contents) + lines = contents.splitlines() + lines = clean_lines(lines) + lines = join_opening_bracket(lines) + lines = perform_indentation(lines) + + text = '\n'.join(lines) + text = strip_bracket_template_tags(text) + + for pattern, substitute in ((r'\n{3,}', '\n\n\n'), (r'^\n', ''), (r'\n$', '')): + text = re.sub(pattern, substitute, text, re.MULTILINE) + + return text + '\n' + + +def format_config_file(file_path, original_backup_file_path=None, verbose=True): + """ + Performs the formatting on the given file. The function tries to detect file encoding first. + :param file_path: path to original nginx configuration file. This file will be overridden. + :param original_backup_file_path: optional path, where original file will be backed up. + :param verbose: show messages + """ + encodings = ('utf-8', 'latin1') + + encoding_failures = [] + chosen_encoding = None + + for enc in encodings: + try: + with codecs.open(file_path, 'r', encoding=enc) as rfp: + original_file_content = rfp.read() + chosen_encoding = enc + break + except ValueError as e: + encoding_failures.append(e) + + if chosen_encoding is None: + raise Exception('none of encodings %s are valid for file %s. Errors: %s' + % (encodings, file_path, [e.message for e in encoding_failures])) + + assert original_file_content is not None + + with codecs.open(file_path, 'w', encoding=chosen_encoding) as wfp: + wfp.write(format_config_contents(original_file_content)) + + if verbose: + print("Formatted file '%s' (detected encoding %s)." % (file_path, chosen_encoding)) + + if original_backup_file_path: + with codecs.open(original_backup_file_path, 'w', encoding=chosen_encoding) as wfp: + wfp.write(original_file_content) + if verbose: + print("Original saved to '%s'." % original_backup_file_path) + + +if __name__ == "__main__": + arg_parser = argparse.ArgumentParser(description=__doc__) + + arg_parser.add_argument("-v", "--verbose", action="store_true", help="show formatted file names") + arg_parser.add_argument("-b", "--backup-original", action="store_true", help="backup original config file") + arg_parser.add_argument("config_files", nargs='+', help="configuration files to format") + + args = arg_parser.parse_args() + + for config_file_path in args.config_files: + backup_file_path = config_file_path + '~' if args.backup_original else None + format_config_file(config_file_path, backup_file_path, args.verbose)