LINUX.ORG.RU

Как использовать tor «Правильно» или свой torify на setgid

 


4

4

Просьба ногами не бить нигде не нашел похожего метода или утили

Всё на ваш страх и риск

Трафик на тор перенаправляем при помощи iptables Правила взял отсюда https://trac.torproject.org/projects/tor/wiki/doc/TransparentProxy Сделал фильтр по пользователям (убрал всю не OUTPUT цепочку к оставшимся правилам добавил фильтр по GID или UID на выбор) Получившийся скрипт

#!/bin/bash
#iptables_torify.bash

dns_port=9053
tor_port=9040
virt_addr="10.192.0.0/10"
non_tor="127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 0.0.0.0/8 100.64.0.0/10 169.254.0.0/16 192.0.0.0/24 192.0.2.0/24 192.88.99.0/24 198.18.0.0/15 198.51.100.0/24 203.0.113.0/24 224.0.0.0/3"

RED='\033[0;31m'
NC='\033[0m'

if [[ "$UID" != "0" ]]; then
    echo -e "${RED}Нужен root!${NC}"
    exit 1
fi

if [[ "$1" == "add" ]]; then
    op="-A"
elif [[ "$1" == "del" ]]; then
    op="-D"
else
    echo -e "${RED}Неизвестная операция '$1'${NC}"
    exit 1
fi

if [[ "$2" == "uid" ]]; then
    if [[ ! "$3" =~ ^[0-9]+$ ]]; then
        echo -e "${RED}Неверный UID '$3'${NC}"
        exit 1
    fi
    filter="--uid-owner"
    owner="$3"
elif [[ "$2" == "gid" ]]; then
    if [[ ! "$3" =~ ^[0-9]+$ ]]; then
        echo -e "${RED}Неверный GID '$3'${NC}"
        exit 1
    fi
    filter="--gid-owner"
    owner="$3"
elif [[ "$2" == "user" ]]; then
    owner=`id -u "$3" 2>/dev/null`
    if [[ ! "$owner" =~ ^[0-9]+$ ]]; then
        echo -e "${RED}Пользователь '$3' не существует${NC}"
        exit 1
    fi
    filter="--uid-owner"
elif [[ "$2" == "group" ]]; then
    owner=`id -g "$3" 2>/dev/null`
    if [[ ! "$owner" =~ ^[0-9]+$ ]]; then
        echo -e "${RED}Пользователь '$3' не существует${NC}"
        exit 1
    fi
    filter="--gid-owner"
else
    echo -e "${RED}Неизвестный фильтр '$2'${NC}"
    exit 1
fi

iptables -t nat "$op" OUTPUT -d "$virt_addr" -p tcp -m tcp -m owner "$filter" "$owner" --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports "$tor_port"
iptables -t nat "$op" OUTPUT -p udp -m udp -m owner "$filter" "$owner" --dport 53 -j REDIRECT --to-ports "$dns_port"
for lan in $non_tor; do
    iptables -t nat "$op" OUTPUT -m owner "$filter" "$owner" -d "$lan" -j RETURN
done
iptables -t nat "$op" OUTPUT -m owner "$filter" "$owner" -o lo -j RETURN
iptables -t nat "$op" OUTPUT -p tcp -m tcp -m owner "$filter" "$owner" --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT --to-ports "$tor_port"

iptables "$op" OUTPUT -m owner "$filter" "$owner" -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j ACCEPT
for lan in $non_tor; do
    iptables "$op" OUTPUT -m owner "$filter" "$owner" -d "$lan" -j ACCEPT
done
iptables "$op" OUTPUT -m owner "$filter" "$owner" -d 127.0.0.1/32 -o lo -j ACCEPT
iptables "$op" OUTPUT -m owner "$filter" "$owner" -d 127.0.0.1/32 -p tcp -m tcp --dport "$tor_port" --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT
iptables "$op" OUTPUT -m owner "$filter" "$owner" -d 127.0.0.1/32 -p udp -m udp --dport "$dns_port" -j ACCEPT
iptables "$op" OUTPUT -m owner "$filter" "$owner" -j DROP
Например sudo iptables_torify.bash add group torify перенаправит трафик всех пользователей с основной группой torify на tor sudo iptables_torify.bash add user myname весь трафик пользователя myname на tor
#/etc/tor/torrc
VirtualAddrNetworkIPv4 10.192.0.0/10
AutomapHostsOnResolve 1
TransPort 9040
DNSPort 9053
Настраиваем пользователя torify
su
useradd torify -m
iptables_torify.bash add group torify
iptables-save >> "/etc/iptables/iptables.rules"
systemctl enable iptables.service
systemctl enable tor
reboot
Залогинившись torify'ем весь наш трафик идет через тор и мы этому (без root) не можем воспрепятствовать (уже хорошо), но хотелось бы без лишних нажатий на клавиатуру Пишем небольшой SUID скрипт на C меняющий GID текущего пользователя на GID пользователя «torify» и запускающий что ему сказали (по аналогии с sudo)
#setgid_torify.cpp
#include <cstdlib>
#include <unistd.h>
#include <string>
#include <cstring>
#include <cassert>
#include <cstdio>

using namespace std;

string e(const char *s) {
    string res;
    for (size_t i = 0, l = strlen(s); i < l; ++i) {
        if(s[i] == '\'') res += "'\\''";
        else res.push_back(s[i]);
    }
    return res;
}

uint32_t id(const char *s) {
    FILE *p = popen(s, "r");
    assert(p);
    char ch;
    uint32_t i = 0;
    do {
        ch = fgetc(p);
        if (ch >= '0' && ch <= '9') i = i * 10 + (ch - '0');
    } while(ch != EOF);
    pclose(p);
    assert(i != 0);
    return i;
}

int main(int argc, const char *argv[]) {
    string s;
    for (int i = 1; i < argc; ++i) {
        s.push_back('\'');
        s += e(argv[i]);
        s.push_back('\'');
        if (i + 1 < argc) s.push_back(' ');
    }
    uint32_t torify_gid = id("id -g torify");
    setgid(torify_gid);
    setuid(getuid());
    if (getgid() == torify_gid)
        return system(s.c_str());
    else
        printf("setgid_torify: failed to setgid\n");
    return 1;
}
g++ setgid_torify.cpp -o setgid_torify -O2 -Wall
sudo chown root:root setgid_torify
sudo chmod 4755 setgid_torify
# Если кто не умеет
Итог (теория) setgid_torify chromium --incognito запускает chromium весь tcp и dns трафик которого идет через tor, весь остальной «дропается» Итог (практика) заходим на browserleaks.com несмотря на то что flash полностью рабочий, «flash leak» не определяет наш настоящий ip (пишет торовский), webrtc leak аналогично


«flash leak» не определяет наш настоящий ip (пишет торовский)

Вых. ноды? Или другие ноды в цепочке? Посмотри еще на 2ip.ru.

anonymous ()

сделайте echoe(), а то от ваших echo -e «${RED}Бла-бла!${NC}» в глазах ребит. Заодно в >&2 направите.

Плюсы в вашем коде совсем не нужны.

Для безопасности надо не просто завернуть аргументы в кавычки, а реально заэскейпить все спец-символы shell-а.

vodz ★★★★★ ()
Ответ на: комментарий от drjerk

(кроме одинарных кавычек)

Вот именно.

И вообще. Я бы не так делал.

1. Должен быть конфигурационный файл, где указан user=torify, чтобы не было захаркожено в двух местах: в скрипте и в бинарнике имя.

2. Вместо popen(«id -g user») посмотрите man getpwnam («user»). У вас же солидная системная утилита!

3. Вместо system юзайте execvp, тогда точно с эскейпингом не промахнётесь, ибо не надо.

4. А уж совсем вообще, то это бинарник не нужен! :) Вам надо скопировать shell и выставить ему sgid. Всё. Вам же не надо за безопасностью следить - этому можно, а этому нельзя. Так ведь?

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 2 )

Мешок плюсов тебе в карму, добрый человек.

Bahamut ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.