Signed-off-by: Jan Pavlinec <jan.pavlinec@nic.cz>lilik-openwrt-22.03
@ -0,0 +1,52 @@ | |||
# | |||
# Copyright (C) 02020 CZ.NIC, z. s. p. o. (https://www.nic.cz/) | |||
# | |||
# This is free software, licensed under the GNU General Public License v2. | |||
# See /LICENSE for more information. | |||
# | |||
include $(TOPDIR)/rules.mk | |||
PKG_NAME:=tor-hs | |||
PKG_VERSION:=0.0.1 | |||
PKG_RELEASE:=1 | |||
PKG_MAINTAINER:=Jan Pavlinec <jan.pavlinec@nic.cz> | |||
PKG_LICENSE:=GPL-3.0-or-later | |||
include $(INCLUDE_DIR)/package.mk | |||
define Package/tor-hs | |||
SECTION:=net | |||
CATEGORY:=Network | |||
SUBMENU:=IP Addresses and Names | |||
TITLE:=Tor hidden service configurator | |||
DEPENDS:=+tor | |||
endef | |||
define Package/tor-hs/description | |||
Tor Hidden Service configurator | |||
endef | |||
define Package/tor-hs/conffiles | |||
/etc/config/tor-hs | |||
endef | |||
define Build/Compile | |||
endef | |||
define Build/Install | |||
endef | |||
define Package/tor-hs/install | |||
$(INSTALL_DIR) $(1)/etc/config/ | |||
$(CP) ./files/tor-hs.conf $(1)/etc/config/tor-hs | |||
$(INSTALL_DIR) $(1)/etc/init.d/ | |||
$(INSTALL_BIN) ./files/tor-hs.init $(1)/etc/init.d/tor-hs | |||
$(INSTALL_DIR) $(1)/etc/tor/ | |||
$(INSTALL_BIN) ./files/nextcloud-update.sh $(1)/etc/tor/ | |||
$(INSTALL_DIR) $(1)/usr/libexec/rpcd | |||
$(INSTALL_BIN) ./files/tor_rpcd.sh $(1)/usr/libexec/rpcd/ | |||
endef | |||
$(eval $(call BuildPackage,tor-hs)) |
@ -0,0 +1,104 @@ | |||
# Tor Hidden service configurator | |||
**tor-hs** packages tries to simplify creating of hidden services on OpenWrt routers. | |||
## Requirements | |||
To run **tor-hs**, you need Tor package with uci config support (it was added | |||
with [this commit](https://github.com/openwrt/packages/commit/ca6528f002d74445e3d0a336aeb9074fc337307a) ). | |||
## Instalation | |||
To install package simple run | |||
``` | |||
opkg update | |||
opkg install tor-hs | |||
``` | |||
## Configuration | |||
Uci configuration is located in **/etc/config/tor-hs** | |||
### Required section of configuration | |||
There is one required section **common** | |||
Example of this section | |||
``` | |||
config tor-hs common | |||
option GenConf "/etc/tor/torrc_hs" | |||
option HSDir "/etc/tor/hidden_service" | |||
option RestartTor "true" | |||
option UpdateTorConf "true" | |||
``` | |||
#### Table with options description | |||
| Type | Name | Default | Description | | |||
| ------ | ------ | ------ | ------ | | |||
| option |GenConf | /etc/tor/torrc_generated|Generated config by tor-hs.| | |||
| option | HSDir |/etc/tor/hidden_service|Directory with meta-data for hidden services (hostname,keys,etc).| | |||
| option | RestartTor | true| It will restart tor after running **/etc/init.d/tor-hs start**.| | |||
| option | UpdateTorConf | true|Update /etc/config/tor with config from **GenConf** option.| | |||
### Hidden service configuration | |||
If you want to create a new hidden service, you have to add a hidden-service section. For every hidden service, there should be a new **hidden-service** section. | |||
Example of hidden service section for ssh server: | |||
``` | |||
config hidden-service | |||
option Name 'sshd' | |||
option Description "Hidden service for ssh" | |||
option Enabled 'false' | |||
option IPv4 '127.0.0.1' | |||
#public port=2222, local port=22 | |||
list PublicLocalPort '2222;22' | |||
``` | |||
#### Table with options description | |||
| Type | Name | Example value | Description | | |||
| ------ | ------ | ------ | ------ | | |||
| option | Name | sshd| Name of hidden service. It is used as directory name in **HSDir**| | |||
| option | Description| Hidden service for ssh| Description used in **rpcd** service| | |||
| option | Enabled |false| Enable hidden service after running **tor-hs** init script| | |||
| option |IPv4 |127.0.0.1|Local IPv4 address of service. Service could run on another device, in that case OpenWrt will redirect comunication. | | |||
| list | PublicLocalPort| 2222;22| Public port is port accesible via Tor network. Local port is normal port of service.| | |||
|option| HookScript |'/etc/tor/nextcloud-update.php'| Path to script which is executed after starting tor-hs. Script is executed with paramters **--update-onion** **hostname** . Hostname is replaced with Onion v3 address for given hidden service. | |||
## Running service | |||
To enable tor-hs service run | |||
``` | |||
/etc/init.d/tor-hs enable | |||
/etc/init.d/tor-hs start | |||
``` | |||
In case you enabled option *RestartTor* and *UpdateTorConf* hidden service should be running. | |||
Otherwise, you should also restart tor daemon. | |||
``` | |||
/etc/init.d/tor restart | |||
``` | |||
After that you should also restart rpcd daemon, so you can use tor-hs RPCD service. | |||
``` | |||
/etc/init.d/rpcd restart | |||
``` | |||
### RPCD | |||
RPCD servis helps users to access basic informations about hidden services on router. After running HS it contains onion url for given hidden service in hostname value. | |||
``` | |||
root@turris:/# ubus call tor_rpcd.sh list-hs '{}' | |||
{ | |||
"hs-list": [ | |||
{ | |||
"name": "sshd", | |||
"description": "Hidden service for ssh", | |||
"enabled": "1", | |||
"ipv4": "127.0.0.1", | |||
"hostname": "****hidden-service-hostname****.onion", | |||
"ports": [ | |||
"22;22" | |||
] | |||
} | |||
] | |||
} | |||
``` | |||
@ -0,0 +1,44 @@ | |||
#!/bin/sh | |||
# This is example script for tor-hs uci config | |||
# HookScript option. Script is then called after running | |||
# hidden service. | |||
# It disables trusted domain check for nextcloud. | |||
NEXTCLOUD_CLI_SCRIPT="/srv/www/nextcloud/occ" | |||
nextcloud_cli() { | |||
sudo -u nobody php-cli "$NEXTCLOUD_CLI_SCRIPT" "$@" | |||
} | |||
nextcloud_add_domain() { | |||
onion="$1" | |||
if [ -n "$onion" ] && nextcloud_cli config:system:get trusted_domains |grep "$onion" ; then | |||
echo "Info: Trusted domains already disabled. Nothing to do." >&2 | |||
else | |||
echo "Info: Disabling trusted domains." >&2 | |||
nextcloud_cli config:system:set trusted_domains 1000 --value=$onion | |||
fi | |||
} | |||
print_help() { | |||
echo "Help" | |||
} | |||
# Check occ command | |||
[ -f "$NEXTCLOUD_CLI_SCRIPT" ] || { | |||
echo "Error: occ command not found!" >&2 | |||
exit 1 | |||
} | |||
################################################################ | |||
case "$1" in | |||
--update-onion) | |||
nextcloud_add_domain "$2" | |||
;; | |||
*) | |||
print_help | |||
;; | |||
esac |
@ -0,0 +1,22 @@ | |||
config tor-hs common | |||
#option GenConf "/etc/tor/torrc_hs" | |||
option GenConf "/etc/tor/torrc_generated" | |||
option HSDir "/etc/tor/hidden_service" | |||
option RestartTor "true" | |||
option UpdateTorConf "true" | |||
#config hidden-service | |||
# option Name 'sshd' | |||
# option Description "Hidden service for ssh" | |||
# option Enabled 'false' | |||
# option IPv4 '127.0.0.1' | |||
# #public port=2222, local port=22 | |||
# list PublicLocalPort '2222;22' | |||
#config hidden-service | |||
# option Name 'nextcloud' | |||
# option Description "Hidden service for Nextcloud" | |||
# option Enabled 'false' | |||
# option IPv4 '127.0.0.1' | |||
# option HookScript '/etc/tor/nextcloud-update.sh' | |||
# list PublicLocalPort '80;80' |
@ -0,0 +1,116 @@ | |||
#!/bin/sh /etc/rc.common | |||
START=52 | |||
STOP=52 | |||
USE_PROCD=1 | |||
TORRC_FILE=/etc/tor/torrc_generated # file with torrc config | |||
HS_DIR_PATH=/etc/tor/hidden_service #hidden service directory path | |||
TOR_USER=tor | |||
clean_hs() { | |||
local name="" | |||
} | |||
config_tor() { | |||
local restart_tor update_config | |||
config_get_bool restart_tor "common" RestartTor | |||
config_get_bool update_config "common" UpdateTorConf | |||
tail_conf=$(uci show tor.conf.tail_include 2>/dev/null) | |||
head_conf=$(uci show tor.conf.head_include 2>/dev/null) | |||
echo "tail_conf $tail_conf" | |||
if [ "$update_config" = "1" ]; then | |||
if [ -n "$(echo $tail_conf | grep $TORRC_FILE)" ] || [ -n "$(echo $head_conf | grep $TORRC_FILE)" ]; then | |||
echo "Info. Not updating tor configuration" | |||
else | |||
#uci add_list | |||
echo "Info. Updating tor configuration" | |||
uci add_list tor.conf.tail_include="$TORRC_FILE" | |||
uci commit tor | |||
fi | |||
fi | |||
if [ "$restart_tor" = "1" ]; then | |||
/etc/init.d/tor restart | |||
fi | |||
} | |||
handle_hs_ports_conf() { | |||
local public_port local_port | |||
local value="$1" | |||
local ipv4="$2" | |||
local name="$3" | |||
public_port=$(echo "$value"|awk -F';' '{print $1}') | |||
local_port=$(echo "$value"|awk -F';' '{print $2}') | |||
echo "HiddenServicePort $public_port $ipv4:$local_port">>$TORRC_FILE | |||
} | |||
parse_hs_conf() { | |||
local name public_port local_port enable_hs ipv4 | |||
local config="$1" | |||
config_get name "$config" Name | |||
config_get description "$config" Description | |||
config_get_bool enable_hs "$config" Enabled 0 | |||
config_get ipv4 "$config" IPv4 | |||
if [ "$enable_hs" = "1" ]; then | |||
mkdir -p "$HS_DIR_PATH/$name" | |||
chown "$TOR_USER":"$TOR_USER" "$HS_DIR_PATH/" | |||
chown "$TOR_USER:$TOR_USER" "$HS_DIR_PATH/$name" | |||
chmod 700 "$HS_DIR_PATH/" | |||
chmod 700 "$HS_DIR_PATH/$name/" | |||
echo "HiddenServiceDir $HS_DIR_PATH/$name" >>$TORRC_FILE | |||
config_list_foreach "$config" PublicLocalPort handle_hs_ports_conf "$ipv4" "$name" | |||
fi | |||
} | |||
parse_hs_conf_hooks() { | |||
local name hook_script enable_hs hostname_file | |||
local config="$1" | |||
config_get enable_hs "$config" Enabled 0 | |||
config_get hook_script "$config" HookScript | |||
config_get name "$config" Name | |||
hostname="$HS_DIR_PATH/$name/hostname" | |||
# check if we should run hook_script | |||
if [ "$enable_hs" = "true" ] && [ -x "$hook_script" ] && [ -f "$hostname" ] ; then | |||
hostname_uri=$(cat "$hostname") | |||
# call hook script | |||
$hook_script "--update-onion" "$hostname_uri" | |||
fi | |||
} | |||
parse_common_conf() { | |||
local hs_dir generated_config | |||
config_get generated_config "common" GenConf | |||
config_get hs_dir "common" HSDir | |||
[ -n "$hs_dir" ] && HS_DIR_PATH="$hs_dir" | |||
[ -n "$generated_config" ] && TORRC_FILE="$generated_config" | |||
} | |||
start_service() { | |||
config_load tor-hs | |||
# clean config | |||
echo "" > $TORRC_FILE # clean config | |||
# load common config | |||
parse_common_conf | |||
# load hs service | |||
config_foreach parse_hs_conf hidden-service | |||
# update tor config | |||
config_tor | |||
# load and run tor-hs hooks | |||
config_foreach parse_hs_conf_hooks hidden-service | |||
} |
@ -0,0 +1,69 @@ | |||
#!/bin/sh | |||
. /lib/functions.sh | |||
get_onion_hostname() { | |||
local name="$1" | |||
config_get hs_dir common HSDir | |||
if [ -f "$hs_dir/$name/hostname" ]; then | |||
cat "$hs_dir/$name/hostname" | |||
fi | |||
} | |||
get_port_list() { | |||
local config="$1" | |||
config_get ports "$config" PublicLocalPort | |||
tmp="$(echo $ports |sed "s| |','|g")" | |||
echo -ne "['$tmp']" | |||
} | |||
parse_hs_conf() { | |||
local name description public_port local_port enable_bool public_local_port ipv4 | |||
local config="$1" | |||
local custom="$2" | |||
config_get name "$config" Name | |||
config_get description "$config" Description | |||
config_get_bool enable_hs "$config" Enabled 0 | |||
config_get ipv4 "$config" IPv4 | |||
hostname="$(get_onion_hostname $name)" | |||
port_list="$(get_port_list $config)" | |||
echo "{" | |||
echo \"name\":\"$name\", | |||
echo \"description\":\"$description\", | |||
echo \"enabled\":\"$enable_hs\", | |||
echo \"ipv4\":\"$ipv4\", | |||
echo \"hostname\":\"$hostname\", | |||
echo \"ports\":$port_list | |||
echo "}," | |||
} | |||
get_tor_hs_list() { | |||
config_load tor-hs | |||
echo "{" | |||
echo '"hs-list":[' | |||
config_foreach parse_hs_conf hidden-service | |||
echo "]" | |||
echo "}" | |||
} | |||
case "$1" in | |||
list) | |||
echo '{ "list-hs": { } }' | |||
;; | |||
call) | |||
case "$2" in | |||
list-hs) | |||
# return json object | |||
get_tor_hs_list | |||
;; | |||
esac | |||
;; | |||
esac | |||