gitweb on apache

# projects web page will be: https://192.168.1.8/gitweb/
# Create a git project (e.g. testproject.git):
# mkdir -p /opt/GITRepositories/testproject.git
# cd /opt/GITRepositories/testproject.git
# git init --bare --shared
# cp -v /opt/GITRepositories/test.git/hooks/post-update.sample /opt/GITRepositories/test.git/hooks/post-update
# now https://192.168.1.8/testproject.git is ready for cloning:
# git clone https://192.168.1.8/testproject.git

# cat /etc/httpd/conf.d/git.conf
SetEnv GIT_PROJECT_ROOT /opt/GITRepositories
SetEnv GIT_HTTP_EXPORT_ALL

<LocationMatch "^/[^/]+\.git(/.*)">
	AuthType Basic
	AuthName "Git Access"
	AuthUserFile "/opt/GITRepositories/committers.txt"
	Require valid-user
	# Require group committers
</LocationMatch>

AliasMatch ^/([^/]+\.git)/(objects/[0-9a-f]{2}/[0-9a-f]{38})$			/opt/GITRepositories/$1/$2
AliasMatch ^/([^/]+\.git)/(objects/pack/pack-[0-9a-f]{40}.(pack|idx))$	/opt/GITRepositories/$1/$2
ScriptAliasMatch \
		"(?x)^/([^/]+\.git/(HEAD | \
						info/refs | \
						objects/(info/[^/]+ | \
								[0-9a-f]{2}/[0-9a-f]{38} | \
								pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
						git-(upload|receive)-pack))$" \
		/usr/libexec/git-core/git-http-backend/$1

# ScriptAlias /gitweb	/var/www/git/gitweb.cgi
Alias /gitweb /var/www/git
<Directory /var/www/git>
	AuthType Basic
	AuthName "Git Access"
	AuthUserFile "/opt/GITRepositories/committers.txt"
	Require valid-user

	Options +ExecCGI
	AddHandler cgi-script .cgi
	DirectoryIndex gitweb.cgi
</Directory>

# grep -i -P "^[^#]" /etc/gitweb.conf 
$projects_list_description_width = "50";
$projectroot = "/opt/GITRepositories";
$home_link_str = "projects";
$base_url = "https://192.168.1.8/gitweb/";
@git_base_url_list = qw(https://192.168.1.8)
see also Basic authentication password creation

Angularjs 2

http://embed.plnkr.co/qZf6yv/

https://benmccormick.org/2015/09/14/es5-es6-es2016-es-next-whats-going-on-with-javascript-versioning/

http://onehungrymind.com/build-a-simple-website-with-angular-2/
http://blog.mgechev.com/2016/06/26/tree-shaking-angular2-production-build-rollup-javascript/
https://scotch.io/tutorials/use-the-angular-cli-for-faster-angular-2-projects
https://www.smashingmagazine.com/2014/06/building-with-gulp/

compatibility
https://angular.io/docs/ts/latest/guide/browser-support.html

angular 2 project seed
https://github.com/angularclass/awesome-angular2#current-browser-support-for-angular-2
https://angularclass.github.io/angular2-webpack-starter/
https://github.com/AngularClass/angular2-webpack-starter
https://www.npmjs.com/package/angular2-webpack-starter
https://github.com/mgechev/angular-seed
https://github.com/NathanWalker/angular-seed-advanced
http://www.devacron.com/angular2-github-boilerplate-repositories/
http://stackoverflow.com/questions/29649578/available-yeoman-generator-for-angular-2

webpack
https://webpack.github.io/docs/
http://stackoverflow.com/questions/39548175/can-someone-explain-webpacks-commonschunkplugin
https://blog.madewithlove.be/post/webpack-your-bags/
http://webpack.github.io/analyse/

webpack lazy loading
not working for me
https://github.com/Quramy/angular2-load-children-loader
https://github.com/Quramy/ng2-lazy-load-demo

rxjs
http://blog.falafel.com/introduction-rxjs-angular2/
http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html

typings
https://github.com/typings/typings
https://neoheurist.wordpress.com/2016/06/20/definitely-typed/
https://blog.ionic.io/ionic-and-typings/
https://blog.mariusschulz.com/2014/05/19/using-typescripts-type-definition-files-to-get-tooling-support-for-plain-javascript

Migrating from 2.x to 3.0
http://getbootstrap.com/migration/

basics
https://egghead.io/lessons/typescript-installing-typescript-and-running-the-typescript-compiler-tsc?course=up-and-running-with-typescript
https://egghead.io/courses/angular-2-fundamentals
https://remysharp.com/2010/10/08/what-is-a-polyfill

basics javascript
https://www.safaribooksonline.com/library/view/learning-javascript-design/9781449334840/ch11.html
https://www.safaribooksonline.com/library/view/learning-javascript-design/9781449334840/ch11s01.html
https://www.safaribooksonline.com/library/view/learning-javascript-design/9781449334840/ch11s02.html
https://www.safaribooksonline.com/library/view/learning-javascript-design/9781449334840/ch11s03.html

nodejs
http://stackoverflow.com/questions/8455290/install-different-versions-of-nodejs
https://github.com/tj/n

initialize a node.js project (this creates package.json)
node init

sass vs less
https://css-tricks.com/sass-vs-less/

Immediately-Invoked Function Expression (IIFE)
http://benalman.com/news/2010/11/immediately-invoked-function-expression/

basics webpack
http://onehungrymind.com/build-a-simple-website-with-angular-2/
https://github.com/simpulton/angular2-website-routes.git
sudo npm list -g --depth=0
sudo npm install -verbose webpack -g
webpack --progress --colors -d
webpack --progress --colors -d --config webpack.config.js

http://semaphoreci.com/community/tutorials/setting-up-angular-2-with-webpack
https://github.com/gonzofish/semaphore-ng2-webpack.git
https://docs.npmjs.com/cli/search
npm search angular-in-memory-web-api
install dev dependencies:
npm install --dev -> deprecated, use the following below
npm install --only=dev
ERROR
	gigi@gigi-desktop:~/Projects/semaphore-ng2-webpack$ node start
	module.js:328
		throw err;
		^
	Error: Cannot find module '/********/Projects/semaphore-ng2-webpack/start'
		at Function.Module._resolveFilename (module.js:326:15)
		at Function.Module._load (module.js:277:25)
		at Function.Module.runMain (module.js:442:10)
		at startup (node.js:136:18)
		at node.js:966:3
SOLUTION
	it's not "node start" but "npm start"
list dependencies for typings@1.4.0:
sudo npm list typings@1.4.0
other:
npm config list
npm config ls -l
npm config ls -l | grep cache
How to view the dependency tree of a given npm module?
sudo npm install -g npm-remote-ls
npm-remote-ls typings
just view a package
npm view typings@1.4.0
here npm start is equivalent to:
npm install webpack-dev-server@1.14.1 --only=dev
find . -name webpack-dev-server.js
./node_modules/webpack-dev-server/bin/webpack-dev-server.js --progress --display-errors-details --inline --colors --config ./webpack/webpack.dev.js

npm
https://www.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/
npm install tslint@3.13.0 --dev
tslint --version
npm run lint

debug with WebStorm
https://blog.jetbrains.com/webstorm/2015/09/debugging-webpack-applications-in-webstorm/

webpack multiple entry points
https://github.com/gigihc11/webpack/tree/master/examples/multiple-entry-points
build with (this one uses template.md):
rm js/* 2>/dev/null; node build.js
or install globally webpack@1.13.1:
sudo npm install webpack@1.13.1 -g
then change webpack.config.js:
// var CommonsChunkPlugin = require("../../lib/optimize/CommonsChunkPlugin");
var webpack = require('webpack');
const CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
then build with:
rm js/* 2>/dev/null; webpack

https://github.com/gigihc11/webpack/tree/master/examples/multiple-entry-points
For changing webpack.config.js from "commons" to e.g. "adunate" you'll
need to also change in pageA.html, pageAB.html, template.md.

https://webpack.github.io/docs/shimming-modules.html
http://stackoverflow.com/questions/29596714/new-es6-syntax-for-importing-commonjs-amd-modules-i-e-import-foo-require
https://nodejs.org/api/modules.html#modules_core_modules

angular2-webpack-starter
https://github.com/AngularClass/angular2-webpack-starter
git clone https://github.com/AngularClass/angular2-webpack-starter.git
git checkout material2
install global dependencies:
sudo npm install --global webpack webpack-dev-server karma-cli protractor typescript rimraf
install project dependencies (package.json):
npm install --verbose

Webstorm
Promise and catch keyword are highlighted with red
go to Languages & Frameworks -> JavaScript and select ECMAScript 6

html5 semantic elements and its usage
http://www.encodedna.com/2014/08/html5-semantic-elements-and-its-usage.htm

Angular 2 lazy loading with Webpack
angular2-router-loader is now angular-router-loader
See https://github.com/AngularClass/angular2-webpack-starter.git for a working example.
https://medium.com/@daviddentoom/angular-2-lazy-loading-with-webpack-d25fe71c29c1#.bxpvfgzlw

angular2-webpack-starter + bootstrap
see also "'use:' revered back to 'loader:'" in webpack.test.js
npm install --save-dev bootstrap
npm install --save-dev image-webpack-loader
add to vendor.browser.ts before "if ('production' === ENV)"
// bootstrap 3.3.7:
import 'bootstrap/dist/css/bootstrap';
import 'bootstrap/dist/css/bootstrap-theme';
change webpack.common.js with this:
resolve: {
	extensions: [..., '.css'],
and this:
{
	test: /\.css$/,
	use: ['to-string-loader', 'css-loader'],
	include: /src\//,
	exclude: /node_modules\//
},
// for bootstrap
{
	test: /\.css$/,
	loader: ['style-loader', 'css-loader'],
	exclude: /src\//,
	include: /node_modules\/bootstrap/
},
and this:
// for bootstrap
{
	test: /\.(jpe?g|gif|svg)$/i,
	loaders: [
		// image-webpack-loader chained with the file-loader (equivalent to: file?...!image-webpack?...)
		'file-loader?hash=sha512&digest=hex&name=[hash].[ext]',
		'image-webpack-loader?bypassOnDebug=true&optimizationLevel=7&interlaced=false'
	]
},
{test: /\.png$/, loader: "url-loader?limit=100"},
{test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=1000&mimetype=application/vnd.ms-fontobject"},
{test: /\.(woff|woff2)$/, loader: "url-loader?&limit=1000&mimetype=application/font-woff"},
{test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url-loader?limit=1000&mimetype=application/octet-stream"}

DEVELOPING A TABS COMPONENT IN ANGULAR
AfterContentInit, ContentChildren
http://blog.thoughtram.io/angular/2015/04/09/developing-a-tabs-component-in-angular-2.html
http://juristr.com/blog/2016/02/learning-ng2-creating-tab-component/

difference between @ContentChildren and @ViewChildren
viewProviders vs providers
AfterViewInit, ViewChild, ViewChildren, ContentChild
http://blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/

Fine grained change detection with Angular 2
DoCheck, KeyValueDiffers
http://juristr.com/blog/2016/04/angular2-change-detection/

ChangeDetectionStrategy: OnPush vs Default
http://www.syntaxsuccess.com/viewarticle/change-detection-in-angular-2.0
http://www.syntaxsuccess.com/angular-2-samples/#/demo/change
https://vsavkin.com/change-detection-in-angular-2-4f216b855d4c#.thlsx9ipr

How to use IterableDiffers
http://embed.plnkr.co/qZf6yv/ -> see app.component.ts
excerpt:
ngDoCheck() {
	const changes = this.differ.diff(this.heroes);
	if (changes) {
		console.log('new change');// for splitting up changes
		changes.forEachAddedItem(r => console.log('added ', r));
		changes.forEachRemovedItem(r => console.log('removed ', r))
		changes.forEachMovedItem(r => console.log('moved ', r))
	}
}

Pipes and Internationalization API
https://github.com/andyearnshaw/Intl.js/

Animation
https://css-tricks.com/ease-out-in-ease-in-out/
http://easings.net/ -> click on ease function for cubic-bezier code
transition(':leave', [
  animate('2s cubic-bezier(0.755, 0.05, 0.855, 0.06)', style({
	opacity: 0,
	transform: 'translateY(100%)'
  }))
])

Build error
[at-loader] Checking finished with 4 errors
[at-loader] src/app/gui/components/validation-alerts.component.ts:6:14 
    Cannot find namespace 'jasmine'. 

[at-loader] src/app/gui/components/validation-alerts.component.ts:32:23 
    Cannot find name '$'. 

[at-loader] src/app/gui/components/validation-alerts.component.ts:34:14 
    Cannot find name '$'. 

[at-loader] src/app/gui/components/validation-alerts.component.ts:158:26 
    Cannot find name '$'. 
SOLUTION
search the appropriate tsconfig.json (or all of them - tsconfig*.json) file and add:
  "compilerOptions": {
    "types": [
      "jasmine",
      "jquery",
      ...
    ]

Important details
  • https://angular.io/docs/ts/latest/guide/router.html By default, the router re-uses a component instance when it re-navigates to the same component type without visiting a different component first.
  • When subscribing to an observable in a component, you almost always arrange to unsubscribe when the component is destroyed. There are a few exceptional observables where this is not necessary. The ActivatedRoute observables are among the exceptions. The ActivatedRoute and its observables are insulated from the Router itself. The Router destroys a routed component when it is no longer needed and the injected ActivatedRoute dies with it. Feel free to unsubscribe anyway. It is harmless and never a bad practice. See also route.snapshot
  • Use route parameters to specify a required parameter value within the route URL

Ufw (uncomplicated firewall)

documentation
https://help.ubuntu.com/lts/serverguide/firewall.html
http://manpages.ubuntu.com/manpages/xenial/en/man8/ufw.8.html
http://manpages.ubuntu.com/manpages/xenial/en/man8/ufw-framework.8.html

important files
/etc/ufw/user.rules

Uncomplicated Firewall
# https://help.ubuntu.com/community/UFW
sudo ufw show added
sudo ufw status verbose
sudo ufw show listening
sudo ufw limit ssh
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 32400
sudo ufw allow in from 192.168.1.0/24
sudo ufw allow in on eth1 to 192.168.0.1/32 port 3389 proto tcp comment 'allow RDP access from LAN'
sudo ufw allow from 86.124.74.35/32 to any proto gre comment 'allow VPN with MarchenGarten'
sudo ufw allow from 82.41.48.239 to any port 3389 proto tcp
sudo ufw allow in on enp1s0 to any port 8083
# sudo ufw delete limit 1443
# sudo ufw delete 11 -> removes rule with order number 11
tailf /var/log/kern.log | grep "\[UFW BLOCK\]"
tailf /var/log/syslog | grep "\[UFW BLOCK\]"

transmission firewall with peer-port-random-on-start = false
grep port /********/.config/transmission-daemon/settings.json
sed -i s/"peer-port-random-on-start\": true"/"peer-port-random-on-start\": false"/ /********/.config/transmission-daemon/settings.json
peerport="`grep peer-port\\" /********/.config/transmission-daemon/settings.json | awk '{sub(/,/,\"\",$2); print $2;}'`"
sudo ufw allow $peerport

transmission firewall with peer-port-random-on-start = true
sed -i s/"peer-port-random-on-start\": false"/"peer-port-random-on-start\": true"/ /********/.config/transmission-daemon/settings.json
grep peer-port-random-low /********/.config/transmission-daemon/settings.json
grep peer-port-random-high /********/.config/transmission-daemon/settings.json
# sudo ufw allow proto udp to any port 49152:65535
# sudo ufw allow proto tcp to any port 49152:65535
sudo ufw allow 49152:65535/tcp
sudo ufw allow 49152:65535/udp

show ufw logs
tailf /var/log/kern.log | grep "\[UFW BLOCK\]"
tailf /var/log/syslog | grep "\[UFW BLOCK\]"

enable at startup
# theoretically should work only this but practically doesn't:
sudo sed -i s/"ENABLED=no"/"ENABLED=yes"/ /etc/ufw/ufw.conf
# you should add this too to /etc/rc.local before "exit 0" line:
if ! ufw enable; then 
	echo "Can't start ufw!"
else
	echo "UFW started!"
fi

# Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback
# accepted). You will need to 'disable' and then 'enable' the firewall for
# the changes to take affect.
sudo sed -i s/"IPV6=yes"/"IPV6=no"/ /etc/default/ufw

Configuring port forwarding (add rules to /etc/ufw/before.rules)
# see also http://askubuntu.com/questions/660972/port-forwarding-with-ufw
sudo sed -i s/"DEFAULT_FORWARD_POLICY=\"DROP"/"DEFAULT_FORWARD_POLICY=\"ACCEPT"/ /etc/default/ufw
sudo sed -i s/"#net\/ipv4\/ip_forward"/"net\/ipv4\/ip_forward"/ /etc/ufw/sysctl.conf

turn off ipv6 autoconfiguration
sudo sed -i s/"#net\/ipv6\/conf\/default\/autoconf=0"/"net\/ipv6\/conf\/default\/autoconf=0"/ /etc/ufw/sysctl.conf
sudo sed -i s/"#net\/ipv6\/conf\/all\/autoconf=0"/"net\/ipv6\/conf\/all\/autoconf=0"/ /etc/ufw/sysctl.conf

configuration status
grep -nr 'ENABLED' /etc/ufw/ufw.conf
grep -nr -P "DEFAULT_FORWARD_POLICY|IPV6=" /etc/default/ufw
grep -nr -P "net\/ipv4\/ip_forward|net\/ipv6\/conf\/default\/autoconf|net\/ipv6\/conf\/all\/autoconf" /etc/ufw/sysctl.conf

deny access to an ip
sudo ufw deny from 146.185.223.4

limit access to an ip
sudo ufw insert 1 limit from 154.16.3.214 comment 'uri abuser limited to anywhere'
sudo ufw insert 1 limit in proto tcp from 154.16.3.214 to 192.168.1.31 port 80,443,49152:65535 comment 'tcp abuser limited to 192.168.1.31 on 80,443,49152:65535'
sudo ufw insert 1 limit in proto udp from 154.16.3.214 to 192.168.1.31 port 80,443,49152:65535 comment 'udp abuser limited to 192.168.1.31 on 80,443,49152:65535'

Redirect from 172.20.19.7:80 to 127.0.0.1:3000 (172.20.19.7 is on eth0 interface)
http://ipset.netfilter.org/iptables-extensions.man.html

# http://serverfault.com/questions/211536/iptables-port-redirect-not-working-for-localhost
# The locally generated packets does not pass via the PREROUTING chain!
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -a | grep 'net.ipv4.ip_forward'

https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt
http://unix.stackexchange.com/questions/111433/iptables-redirect-outside-requests-to-127-0-0-1
sudo sysctl -w net.ipv4.conf.eth0.route_localnet=1
sudo sysctl -a | grep 'net.ipv4.conf.eth0.route_localnet'

# It seems that you could configure the above in /etc/ufw/sysctl.conf too though I haven't tested it.
/etc/default/ufw should have DEFAULT_FORWARD_POLICY="ACCEPT"

# in /etc/ufw/before.rules before filter section:
*nat
:PREROUTING ACCEPT [0:0]
# -A = append last
# -I = insert first
#
# sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000
# -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 3000
#
# sudo iptables -t nat -I PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:3000
-I PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:3000
#
COMMIT

# you'll need also the rule below  
sudo ufw allow to 127.0.0.1 port 3000
# otherwise external users won't be allowed on port 80 and you'll see logs like this:
[UFW BLOCK] IN=eth0 OUT= MAC=3c:11:11:f0:21:11:00:11:0f:09:00:04:08:00 SRC=11.111.114.201 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=63 ID=54696 DF PROTO=TCP SPT=9194 DPT=3000 WINDOW=26280 RES=0x00 SYN URGP=0

sudo ufw disable && sudo ufw enable

APT (Advanced Package Tool)

search packages by name using REGEX
see http://newbiedoc.sourceforge.net/tutorials/apt-get-intro/info.html
apt-cache search libapr
apt-cache search 'php.*sql'
apt-cache search apache.\*perl
apt-cache search elvis\|vim

list the contents of a (not-installed) package
see https://unix.stackexchange.com/questions/6311/how-to-find-out-which-not-installed-package-a-file-belongs-to
apt-file list mysql-client-5.1

showing package information
apt-cache showpkg libconfig-dev

check a package status
dpkg --get-selections | grep apache2

find which package contains a file
use also http://www.debian.org/distrib/packages#search_contents
apt-file update
apt-file -i search --regex /knemo-modem-transmit-receive.svg$ -> doesn't work for this specific file
apt-file -i search knemo-modem-transmit-receive.svg -> doesn't work for this specific file
apt-file search fusil/fusil-ogg123 -> this works so for the above fails maybe the repository from where the files were installed now is missing
dpkg --search knemo-modem-transmit-receive.svg -> but this one works (with owning package installed)
dpkg -S 'doc/*sql'

show package summary & contents
dpkg -l mongodb-compass
dpkg -L kibana
dpkg-query -L kibana

install deb file with automatic dependency resolution
sudo apt-get install ./Downloads/skypeforlinux-64.deb

install all packages you need to compile $PACKAGENAME
https://askubuntu.com/questions/481/how-do-i-find-the-package-that-provides-a-file
apt-get build-dep $PACKAGENAME

list repositories
grep -rh ^deb /etc/apt/sources.list /etc/apt/sources.list.d/

remove repository
sudo add-apt-repository --remove ppa:whatever/ppa

ssh, http and https multiplexing

This is about how to have the ssh and http(s) server share the same port (e.g. 80 or 443 port).
This is really cool :).

# Used sources:
# http://yalis.fr/cms/index.php/post/2014/02/22/Multiplex-SSH-and-HTTPS-on-a-single-port
# http://blog.cppse.nl/apache-proxytunnel-ssh-tunnel
# http://serverfault.com/questions/355271/ssh-over-https-with-proxytunnel-and-nginx
# http://tyy.host-ed.me/pluxml/article4/port-443-for-https-ssh-and-ssh-over-ssl-and-more
# http://ipset.netfilter.org/iptables.man.html
# http://ipset.netfilter.org/iptables-extensions.man.html
# http://man7.org/linux/man-pages/man8/ip-rule.8.html
# http://lartc.org/howto/lartc.netfilter.html
# http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=Unassigned
# https://cloud.githubusercontent.com/assets/2137369/15272097/77d1c09e-1a37-11e6-97ef-d9767035fc3e.png
# http://www.adminsehow.com/2011/09/iptables-packet-traverse-map/

### begin sshttp setup 1
# https://github.com/stealth/sshttp
# Below are the preparations for this setup:
# sshttpd listens on 80 for ssh and http connections. It forwards to ssh:1022 and nginx:880.
# Will work these:
ssh -p 1022 gigi@127.0.0.1		-> access tried from within 192.168.1.31 host
ssh -p 1022 gigi@192.168.1.31	-> access tried from within 192.168.1.31 host
ssh -p 80 gigi@adrhc.go.ro		-> access tried from within 192.168.1.31 host or from internet
http://127.0.0.1/public/		-> access tried from within 192.168.1.31 host
http://127.0.0.1:880/public/	-> access tried from within 192.168.1.31 host
http://192.168.1.31:880/public/	-> access tried from within 192.168.1.31 host
http://192.168.1.31/public/		-> access tried from 192.168.1.31's LAN
http://adrhc.go.ro/public/		-> access tried from within 192.168.1.31 host or from internet
# Won't work this:
ssh -p 1022 gigi@adrhc.go.ro	-> access tried from within 192.168.1.31 host or from internet
http://192.168.1.31/public/		-> access tried from within 192.168.1.31 host
http://adrhc.go.ro:880/public/	-> access tried from within 192.168.1.31 host or from internet

# /etc/modules
modprobe nf_conntrack_ipv4
modprobe nf_conntrack
echo "nf_conntrack" >> /etc/modules
echo "nf_conntrack_ipv4" >> /etc/modules

# in /etc/ssh/sshd_config make sure to have:
# Port 1022
# Banner /etc/sshd-banner.txt 
# Makefile uses the content of /etc/sshd-banner.txt, e.g.:
# SSH_BANNER=-DSSH_BANNER=\"adrhc\'s\ SSH\ server\"
cat /etc/sshd-banner.txt
adrhc's SSH server

# configure nf-setup, e.g. for sshttpd.service below should be:
DEV="eth0"
SSH_PORT=1022
# HTTP_PORT=1443
HTTP_PORT=880
# also you could add this afterwards in order not to run nf-setup if already run:
if [ "`iptables -t mangle -L | grep -v -P "^ufw-" | grep -P "^DIVERT.+tcp spt:$HTTP_PORT"`" != "" ]; then
	echo "sshttp netfilter rules already applied ..."
	exit 0
fi
echo "applying sshttp netfilter rules ..."

# for nginx or apache take care of address binding not to overlap with sshttpd.service, e.g.:
#    server {
#        listen	127.0.0.1:80;
#        listen	127.0.0.1:880;
#        # listen 192.168.1.31:80; -> used/bound by sshttpd.service below
#        listen	192.168.1.31:880;

# install the systemd sshttpd.service defined below:
sudo chown root: /etc/systemd/system/sshttpd.service && sudo chmod 664 /etc/systemd/system/sshttpd.service && sudo systemctl daemon-reload; cp -v $HOME/compile/sshttp/nf-setup $HOME/apps/bin

# systemd sshttpd.service:
[Unit]
# see https://github.com/stealth/sshttp
Description=SSH/HTTP(S) multiplexer
# for any address binding conflict that occurs between ufw, ssh, nginx and sshttp I want ufw, ssh and nginx to win against sshttp
After=network.target
# sudo iptables -L | grep -v -P "^ufw-" | grep -P "1022|1443|880|DIVERT|DROP|ssh"
# sudo iptables -t mangle -L | grep -v -P "^ufw-" | grep -P "1022|1443|880|DIVERT|DROP|ssh"
[Service]
Type=forking
RuntimeDirectory=sshttpd
ExecStartPre=-/bin/chown nobody: /run/sshttpd
ExecStartPre=-/home/gigi/apps/bin/nf-setup
Restart=on-failure
RestartSec=3
TimeoutStartSec=5
TimeoutStopSec=5
# using 443 for sshttpd:
# ssh -p 443 gigi@adrhc.go.ro
# wget --no-check-certificate https://adrhc.go.ro/
# ExecStart=/home/gigi/apps/bin/sshttpd -n 4 -S 1022 -H 1443 -L 443 -l 192.168.1.31 -U nobody -R /run/sshttpd
# using 80 for sshttpd:
# ssh -p 80 gigi@adrhc.go.ro
# wget http://adrhc.go.ro/public
ExecStart=/home/gigi/apps/bin/sshttpd -n 4 -S 1022 -H 880 -L 80 -l 192.168.1.31 -U nobody -R /run/sshttpd
[Install]
WantedBy=multi-user.target

### begin sshttp setup 2 (read first sshttp step 1)
# Below are the preparations for this setup:
# sshttpd listens on 444 for ssh and https connections. 
# sshttpd forwards to ssh:1022 or stunnel:1443.
# stunnel:1443 forwards to nginx:127.0.0.1:1080 or ssh:127.0.0.1:22 based on sni.
# the original remote client's ip is accessible (only for https but not ssh) with $realip_remote_addr (http://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header)

# Issue: any redirect (301 or 302) used in the server 127.0.0.1:1080 defined below will set Location header to http instead of https
# - see sshttp setup 3 for a solution 
# - see https://forum.nginx.org/read.php?2,269623,269647#msg-269647 (listen proxy_protocol and rewrite redirect scheme) for a better? solution:
src/http/ngx_http_header_filter_module.c: 
#if (NGX_HTTP_SSL) 
if (c->ssl || port == 443) { 
*b->last++ ='s'; 
} 
#endif 

# Won't work Transmission remote GUI but the web page will still work.
# ERROR (while using Transmission remote GUI):
	2016/09/19 15:03:42 [error] 5562#0: *2431 broken header: ">:azX���g��^}q�/���A��Rp(���n3��0�,�(�$��
	����kjih9876�����2�.�*�&���=5��/�+�'�#��	����g@?>3210����EDCB�1�-�)�%���</�A���
	�                                                                                      ��
	�g
		127.0.0.1
	" while reading PROXY protocol, client: 127.0.0.1, server: 127.0.0.1:443
	NӾHu|���4|�sf��Q�j$������0�,�(�$��432 broken header: ">:LM2V
	����kjih9876�����2�.�*�&���=5��/�+�'�#��	����g@?>3210����EDCB�1�-�)�%���</�A���
	�                                                                                      ��
	�g
		127.0.0.1
	" while reading PROXY protocol, client: 127.0.0.1, server: 127.0.0.1:443

# in systemd sshttpd.service change to:
# router: 443 -> 444 -> also make sure ufw allows 444
# ssh -p 443 gigi@adrhc.go.ro
# wget --no-check-certificate https://adrhc.go.ro/
ExecStart=/********/apps/bin/sshttpd -n 4 -S 1022 -H 1443 -L 444 -l 192.168.1.31 -U nobody -R /run/sshttpd

# in nginx add this "magic" server:
server {
	listen 127.0.0.1:1080 default_server proxy_protocol;
	include xhttpd_1080_proxy.conf;
	port_in_redirect off;
	# change also fastcgi_params! (see below)
	... your stuff ...
}

# xhttpd_1080_proxy.conf:
set_real_ip_from 192.168.1.0/24;
set_real_ip_from 127.0.0.0/8;
# set_real_ip_from ::1/32; -> doesn't work for me
real_ip_header proxy_protocol;
set $real_internet_https "on";
set $real_internet_port "443";

# in fastcgi_params have (besides your stuff):
# This special fastcgi_params must be used only by "magic server" (127.0.0.1:1080)!
fastcgi_param HTTPS $real_internet_https if_not_empty;
fastcgi_param SERVER_PORT $real_internet_port if_not_empty;

# stunnel.conf for server side
# sudo killall stunnel; sleep 1; sudo bin/stunnel etc/stunnel/stunnel.conf
pid = /run/stunnel.pid
debug = 4
output = /********/apps/log/stunnel.log
options = NO_SSLv2
compression = deflate
cert = /********/apps/etc/nginx/certs/adrhc.go.ro-server-pub.pem
key = /********/apps/etc/nginx/certs/adrhc.go.ro-server-priv-no-pwd.pem
[tls]
accept = 192.168.1.31:1443
connect = 127.0.0.1:1080
protocol = proxy
[ssh]
sni = tls:tti.go.ro
connect = 127.0.0.1:22
renegotiation = no
debug = 5
cert = /********/apps/etc/nginx/certs/adrhc.go.ro-server-pub.pem
key = /********/apps/etc/nginx/certs/adrhc.go.ro-server-priv-no-pwd.pem
[www on any]
sni = tls:*
connect = 127.0.0.1:1080
protocol = proxy

# stunnel.conf for client side
# killall stunnel; sleep 1; stunnel ****stunnel.conf && tailf ****stunnel.log
# ssh -p 1194 gigi@localhost
pid = /****************/temp/stunnel.pid
debug = 4
output = /****************/****stunnel.log
options = NO_SSLv2
[tti.go.ro]
# Set sTunnel to be in client mode (defaults to server)
client = yes  
# Port to locally connect to
accept = 127.0.0.1:1194  
# Remote server for sTunnel to connect to
connect = adrhc.go.ro:443
sni = tti.go.ro
verify = 2
CAfile = /****************/****Temp/Zyxel/adrhc.go.ro-server-pub.pem
# checkHost = certificate's CN field (see "Rejected by CERT at" in stunnel.log for learning CN)
checkHost = adrhc.go.ro
# CAfile = /****************/****Temp/Zyxel/adr-pub.pem
# checkHost = adr

### begin sshttp setup 3 (read first sshttp step 2)
# any redirect (301 or 302) used in the server 127.0.0.1:1080 defined above will go to the https server
# Issue: the original remote client's ip is not accessible (https or ssh)

# you'll need the https nginx configuration for your site listening at least on 127.0.0.1:443
# you no longer need the "magic" server defined above
# How this works:
# browser/stunnel-client useing ssl -> sshttpd:443 -> stunnel[tls to http] using ssl -> stunnel[http to https]

# stunnel.conf for server side
# sudo killall stunnel; sleep 1; sudo bin/stunnel etc/stunnel/stunnel.conf
pid = /run/stunnel.pid
debug = 4
output = /********/apps/log/stunnel.log
options = NO_SSLv2
compression = deflate
cert = /********/apps/etc/nginx/certs/adrhc.go.ro-server-pub.pem
key = /********/apps/etc/nginx/certs/adrhc.go.ro-server-priv-no-pwd.pem
[tls]
accept = 192.168.1.31:1443
connect = 127.0.0.1:1081
protocol = proxy
[ssh]
sni = tls:tti.go.ro
connect = 127.0.0.1:22
renegotiation = no
debug = 5
cert = /********/apps/etc/nginx/certs/adrhc.go.ro-server-pub.pem
key = /********/apps/etc/nginx/certs/adrhc.go.ro-server-priv-no-pwd.pem
[tls to http]
sni = tls:*
connect = 127.0.0.1:1081
# connect = 127.0.0.1:1080
# protocol = proxy
[http to https]
accept = 127.0.0.1:1081
connect = 127.0.0.1:443
client = yes

### begin sslh setup
# https://github.com/yrutschle/sslh
# Here I use ssh:1021 instead of ssh:1022.
sudo apt-get install sslh

sudo useradd -d /nonexistent -M -s /bin/false sslh
# according to https://github.com/yrutschle/sslh#capabilities-support I need:
sudo setcap cap_net_bind_service,cap_net_admin+pe /usr/sbin/sslh-select
sudo getcap -rv /usr/sbin/sslh-select

cat /etc/default/sslh
RUN=yes
DAEMON=/usr/sbin/sslh-select
# with --transparent the local ip is not acceptable:
DAEMON_OPTS="--transparent --timeout 1 --numeric --user sslh --listen 192.168.1.31:334 --ssh 192.168.1.31:1021 --http 192.168.1.31:80 --pidfile /var/run/sslh/sslh.pid"
# without --transparent is acceptable also local ip:
# DAEMON_OPTS="--transparent --timeout 1 --numeric --user sslh --listen 192.168.1.31:334 --ssh 192.168.1.31:1021 --http 127.0.0.1:80 --pidfile /var/run/sslh/sslh.pid"

cat /etc/systemd/system/sslh.service.d/custom.conf 
# cp -v $HOME/bin/systemd-services/sslh-setup.sh $HOME/apps/bin
[Service]
ExecStartPre=-/********/apps/bin/sslh-setup.sh
ExecStart=
ExecStart=/usr/sbin/sslh-select --foreground $DAEMON_OPTS
SuccessExitStatus=15

cat sslh-setup.sh
#!/bin/sh
if [ "`sudo iptables -t mangle -L | grep -P "^SSLH\s.+\sspt:1021"`" != "" ]; then
	echo "SSLH netfilter rules already applied ..."
	exit 0
fi
iptables -t mangle -N SSLH
iptables -t mangle -A OUTPUT --protocol tcp --out-interface eth0 --sport 1021 --jump SSLH
iptables -t mangle -A OUTPUT --protocol tcp --out-interface eth0 --sport 80 --jump SSLH
iptables -t mangle -A SSLH --jump MARK --set-mark 0x1
iptables -t mangle -A SSLH --jump ACCEPT
ip rule add fwmark 0x1 lookup 100
ip route add local 0.0.0.0/0 dev lo table 100

sudo systemctl daemon-reload
sudo systemctl enable sslh
sudo systemctl start sslh