Есть ли способ для некорневых процессов привязываться к" привилегированным " портам в Linux?

это очень раздражает иметь это ограничение на моем поле разработки, когда никогда не будет никаких пользователей, кроме меня.

Я в курсе стандартные обходные пути, но никто из них не делает именно то, что я хочу:

  1. authbind (версия в Debian testing, 1.0, поддерживает только IPv4)
  2. использование iptables REDIRECT target для перенаправления низкого порта на высокий порт (таблица " nat " еще не реализована для ip6tables, IPv6 версия iptables)
  3. sudo (работает как root-это то, чего я пытаюсь избежать)
  4. SELinux (или аналогичный). (Это просто мой dev box, я не хочу вводить много дополнительной сложности.)

есть ли какие-то простые sysctl переменная, позволяющая некорневым процессам привязываться к" привилегированным " портам (портам менее 1024) в Linux, или мне просто не повезло?

EDIT: в некоторых случаях вы можете использование функции для сделать это.

22 ответов


Хорошо, спасибо людям, которые указали на возможности системы и CAP_NET_BIND_SERVICE возможности. Если у вас есть недавнее ядро, действительно можно использовать его для запуска службы как некорневой, но привязки низких портов. Короткий ответ заключается в том, что вы:

setcap 'cap_net_bind_service=+ep' /path/to/program

и тогда в любое время program выполняется, после этого он будет иметь CAP_NET_BIND_SERVICE возможности. setcap находится в пакете debian libcap2-bin.

теперь для предостережений:

  1. вам будет нужно на минимум ядро 2.6.24
  2. это не будет работать, если ваш файл является скриптом. (т. е. использует #! строка для запуска интерпретатора). В этом случае, насколько я понимаю, вам придется применить эту возможность к исполняемому файлу интерпретатора, что, конечно, является кошмаром безопасности, поскольку любая программа, использующая этот интерпретатор, будет иметь эту возможность. Я не смог найти никакого чистого, простого способа обойти эту проблему.
  3. Linux отключит LD_LIBRARY_PATH на любом program что повышенные привилегии, такие как setcap или suid. Так что если ваш program использует собственные .../lib/, возможно, вам придется изучить другой вариант, такой как переадресация портов.

ресурсы:

  • возможности (7) man page. Прочтите это долго и упорно, если вы собираетесь использовать возможности в производственной среде. Есть некоторые действительно сложные детали того, как возможности наследуются через вызовы exec (), которые детализированы здесь.
  • setcap man page
  • "привязка портов ниже 1024 без root на GNU / Linux": документ, который впервые указал мне на setcap.

Примечание: RHEL сначала добавил Это в v6.


стандартный способ-сделать их "setuid", чтобы они запускались как root, а затем они отбрасывают эту привилегию root, как только они привязаны к порту, но прежде чем они начнут принимать соединения с ним. Вы можете увидеть хорошие примеры этого в исходном коде для Apache и INN. Мне сказали, что Lighttpd-еще один хороший пример.

Другим примером является Postfix, который использует несколько демонов, которые общаются через трубы, и только один или два из них (которые делают очень мало кроме accept или emit bytes) запускаются как root, а остальные запускаются с более низкой привилегией.


вы можете сделать перенаправление порта. Это то, что я делаю для сервера политики Silverlight, работающего на Linux box

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300

вы можете настроить локальный SSH-туннель, например, если вы хотите, чтобы порт 80 попал в ваше приложение, связанное с 3000:

sudo ssh $USERNAME@localhost -L 80:localhost:3000 -N

это имеет то преимущество, что работает с серверами сценариев и очень просто.


возможности файлов не идеальны, потому что они могут сломаться после обновления пакета.

идеальным решением, IMHO, должна быть возможность создания оболочки с наследуемым CAP_NET_BIND_SERVICE set.

вот несколько запутанный способ сделать это:

sg $DAEMONUSER "capsh --keep=1 --uid=`id -u $DAEMONUSER` \
     --caps='cap_net_bind_service+pei' -- \
     YOUR_COMMAND_GOES_HERE"

capsh утилита может быть найдена в пакете libcap2-bin в дистрибутивах Debian / Ubuntu. Вот что происходит:

  • sg изменяет идентификатор эффективной группы на идентификатор пользователя демона. Это необходимо, потому что capsh оставляет GID без изменений, и мы определенно не хотим этого.
  • устанавливает бит "сохранить возможности при изменении UID".
  • изменяет UID на $DAEMONUSER
  • сбрасывает все колпачки (в данный момент все колпачки все еще присутствуют из-за --keep=1), за исключением наследуемых cap_net_bind_service
  • выполняет вашу команду ('--'является разделителем)

результатом является процесс с указанным пользователем и группой, и cap_net_bind_service преференции.

в качестве примера строки из ejabberd запуск скрипта:

sg $EJABBERDUSER "capsh --keep=1 --uid=`id -u $EJABBERDUSER` --caps='cap_net_bind_service+pei' -- $EJABBERD --noshell -detached"

два простых варианта:

существует старое (немодное) решение для "демона, который привязывается к низкому Порту и передает управление вашему демону". Это называется inetd (или xinetd). Минусы:

  • ваш демон должен говорить на stdin / stdout (если вы не контролируете демон - если у вас нет источника - тогда это, возможно, showstopper, хотя некоторые службы могут иметь флаг совместимости inetd)
  • новый процесс демона раздвоение для каждого соединения
  • это одно дополнительное звено в цепи

плюсы:

  • доступно на любом старом UNIX
  • после того, как ваш системный администратор настроил конфигурацию, вы можете приступить к разработке (когда вы перестроите свой демон, вы можете потерять возможности setcap? И тогда вам придется вернуться к своему администратору " Пожалуйста, сэр...")
  • демону не нужно беспокоиться об этом сетевом материале, просто нужно поговорить stdin / stdout
  • можно настроить для выполнения демона как пользователя, не являющегося root, по запросу

другая альтернатива: взломанный прокси (netcat или даже что-то более надежной) от привилегированного порта до произвольного порта с высоким номером, где вы можете запустить целевой демон. (Netcat, очевидно, не является производственным решением, но "просто мой dev box", верно?). Таким образом, вы можете продолжать использовать сетевую версию вашего сервера, вам понадобится только root/sudo для запуска прокси (При загрузке) не будет полагаться на сложные / потенциально хрупкие возможности.


мой "стандартный обходной путь" использует socat в качестве перенаправителя пользовательского пространства:

socat tcp6-listen:80,fork tcp6:8080

остерегайтесь, что это не будет масштабироваться, разветвление дорого, но так работает socat.


или исправьте ядро и удалите чек.

(вариант последнего средства, не рекомендуется).


TLDR: для "ответа" (как я его вижу), перейдите к >>TLDR

хорошо, я понял это (на этот раз по-настоящему), ответ на этот вопрос, и этот мой ответ также является способом извинения за продвижение еще один ответ (как здесь, так и в twitter), что я думал, что "лучший", но после попытки, обнаружил, что я ошибался об этом. Учитесь на моей ошибке дети: не продвигайте что-то, пока ты сам не попробуешь!

опять же, я просмотрел все ответы здесь. Я пытался некоторые из них (и решил не пробовать другие, потому что мне просто не нравились решения). Я думал, что решение было использовать systemd С Capabilities= и CapabilitiesBindingSet= настройки. После борьбы с этим в течение некоторого времени, я обнаружил, что это не решение проблемы потому что:

функции предназначены чтобы ограничить корневые процессы!

как мудро заявил ОП, это всегда лучше избегать этого (для всех ваших демонов, если это возможно!).

вы не можете использовать опции, связанные с возможностями с User= и Group= на systemd единица файлы, потому что возможности всегда сброс когда execev (или любой функции) называется. Другими словами, когда systemd вилки и падения свои perms, возможности переустановлены. Это невозможно. вокруг этого, и вся эта логика привязки в ядре является базовой вокруг uid=0, а не возможностей. Это означает, что маловероятно, что возможности никогда не будет правильного ответа на этот вопрос (по крайней мере в ближайшее время). Кстати, setcap, как уже упоминали другие, это не решение. Это не сработало для меня, это не работает хорошо со сценариями, и они сбрасываются в любом случае, когда файл изменяется.

в моей скудной защите я заявил (в комментарии, который я удалил), что Джеймс!--50-->iptables предложение (которое OP также упоминает), было "2-м лучшим решением". :- P

>>TLDR

решение состоит в том, чтобы объединить systemd С on-the-fly iptables команды, как это (взято из DNSChain):

[Unit]
Description=dnschain
After=network.target
Wants=namecoin.service

[Service]
ExecStart=/usr/local/bin/dnschain
Environment=DNSCHAIN_SYSD_VER=0.0.1
PermissionsStartOnly=true
ExecStartPre=/sbin/sysctl -w net.ipv4.ip_forward=1
ExecStartPre=-/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=-/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStartPre=/sbin/iptables -A INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=/sbin/iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStopPost=/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStopPost=/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
User=dns
Group=dns
Restart=always
RestartSec=5
WorkingDirectory=/home/dns
PrivateTmp=true
NoNewPrivileges=true
ReadOnlyDirectories=/etc

# Unfortunately, capabilities are basically worthless because they're designed to restrict root daemons. Instead, we use iptables to listen on privileged ports.
# Capabilities=cap_net_bind_service+pei
# SecureBits=keep-caps

[Install]
WantedBy=multi-user.target

здесь мы выполняем следующее:

  • демон слушает 5333, но соединения успешно принимаются на 53 благодаря iptables
  • мы можем включить команды в самом файле блока, и таким образом мы сохраняем головные боли людей. systemd очищает правила брандмауэра для нас, не забывая удалять их, когда демон не работает.
  • мы никогда не запускаем как root, и мы делаем эскалацию привилегий невозможной (по крайней мере systemd утверждает), предположительно, даже если демон скомпрометирован и устанавливает uid=0.

iptables все еще, к сожалению, довольно уродливый и трудный в использовании полезность. Если демон слушает eth0:0 вместо eth0, например, команды немного разные.


Linux поддерживает возможности для поддержки более детальных разрешений, чем просто "это приложение запускается как root". Одна из этих возможностей CAP_NET_BIND_SERVICE Что касается привязки к привилегированному порту (

к сожалению, я не знаю, как использовать это, чтобы запустить приложение как не root, все еще давая ему CAP_NET_BIND_SERVICE (вероятно, с помощью setcap, но для этого обязательно должно быть существующее решение).


я знаю, что это старый вопрос, но теперь с недавними ядрами (>= 4.3), наконец, есть хороший ответ на это - возможности окружающей среды.

быстрый ответ-захватить копию последней (пока еще неизданной) версии libcap от git и скомпилировать его. Скопируйте полученный результат progs/capsh бинарный где-то (/usr/local/bin хороший выбор). Затем, как root, запустите программу

/usr/local/bin/capsh --keep=1 --user='your-service-user-name' \
    --inh='cap_net_bind_service' --addamb='cap_net_bind_service' \ 
    -- -c 'your-program'

в порядке, мы

  • объявив, что когда мы переключаем пользователей, мы хотим сохранить наши текущие наборы возможностей
  • переключение пользователя и группы на "your-service-user-name"
  • добавлять cap_net_bind_service возможность унаследованных & окружающих наборов
  • разветвление bash -c 'your-command' (поскольку capsh автоматически запускает bash с аргументами после --)

здесь много чего происходит под капотом.

во-первых, мы работаем как root, поэтому по умолчанию мы получаем полный набор способности. В это включена возможность переключения uid & gid с помощью setuid и setgid системных вызовов. Однако обычно, когда программа делает это, она теряет свой набор возможностей - это так, что старый способ удаления root с setuid до сих пор работает. The --keep=1 флаг говорит capsh оформить prctl(PR_SET_KEEPCAPS) syscall, который отключает падение возможностей при изменении пользователя. Фактическое изменение пользователей на capsh происходит с --user флаг, который работает setuid и setgid.

следующая проблема, которую нам нужно решить, - это как установить возможности таким образом, чтобы это продолжалось после того, как мы exec наши дети. Система возможностей всегда имела "унаследованный" набор возможностей, который является " набором возможностей, сохраненных в execve(2)" [функции(7)]. Хотя это звучит так, как будто это решает нашу проблему (просто установите cap_net_bind_service возможность унаследованного, не так ли?), это на самом деле относится только к привилегированным процессам - и нашему процессу больше не является привилегированным, потому что мы уже изменили пользователя (с помощью --user флаг).

новый набор внешних возможностей работает вокруг этой проблемы - это " набор возможностей, которые сохраняются в execve(2) программы, которая не является привилегированной.- Поставив cap_net_bind_service в окружающем наборе, когда capsh exec наша серверная программа, наша программа унаследует эту возможность и сможет привязать слушателей к низким портам.

если вы заинтересованы выучить больше, то возможности страница руководства объясняет это очень подробно. Бег!--5--> через strace также очень информативно!


обновление 2017:

использовать authbind


Намного лучше, чем CAP_NET_BIND_SERVICE или пользовательское ядро.

  • CAP_NET_BIND_SERVICE предоставляет доверие к бинарным, но не контроль над портовым доступом.
  • Authbind предоставляет доверие пользователь / группа и обеспечивает контроль над портовым доступом, и поддерживает как IPv4, так и IPv6 (поддержка IPv6 была добавлена с покойный.)

    1. установка: apt-get install authbind

    2. настройка доступа к соответствующим портам, например 80 и 443 для всех пользователей и групп:

sudo touch/etc/authbind/byport / 80
sudo touch / etc/authbind/byport / 443
sudo chmod 777 / etc/authbind/byport / 80
sudo chmod 777 / etc/authbind/byport / 443

  1. выполнить ваша команда через authbind
    (при необходимости укажите --deep или другие аргументы, см. справочную страницу):

    authbind --deep /path/to/binary command line args
    

    например

    authbind --deep java -jar SomeServer.jar
    

в развитие сказочной рекомендации Джошуа (=не рекомендуется, если вы не знаете, что делаете) взломать ядро:

я впервые опубликовал его здесь.

простой. С нормальным или старым ядром-нет.
Как указывали другие, iptables может передайте порт.
Как также указывали другие, CAP_NET_BIND_SERVICE также может выполнить эту работу.
Конечно, CAP_NET_BIND_SERVICE потерпит неудачу, если вы запустите свою программу из скрипта, если вы не установите cap на интерпретаторе оболочки, что бессмысленно, вы можете также запустить свою службу как root...
например, для Java вы должны применить его к JAVA JVM

sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/lib/jvm/java-8-openjdk/jre/bin/java

очевидно, что это означает, что любая программа Java может связывать системные порты.
Дито для mono/.Сеть.

я также уверен, что xinetd-не лучшая из идей.
Но поскольку оба метода являются взломами, почему бы просто не снять ограничение, сняв ограничение ?
Никто не сказал, что вы должны запустить нормальное ядро, поэтому вы можете просто запустить свое собственное.

вы просто загружаете источник для последнего ядра (или того же, что и в настоящее время). После этого вы идете к:

/usr/src/linux-<version_number>/include/net/sock.h:

там вы ищете эту строку

/* Sockets 0-1023 can't be bound to unless you are superuser */
#define PROT_SOCK       1024

и изменить его к

#define PROT_SOCK 0

если вы не хотите иметь небезопасную ситуацию ssh, вы измените ее на это: #define PROT_SOCK 24

как правило, я бы использовал самую низкую настройку, которая вам нужна, e.g 79 для http или 24 при использовании SMTP на порту 25.

это уже все.
Скомпилируйте ядро и установите его.
Перезагрузить.
Закончено-этот глупый предел ушел, и это также работает для скриптов.

вот как вы компилируете ядро:

https://help.ubuntu.com/community/Kernel/Compile

# You can get the kernel-source via package linux-source, no manual download required
apt-get install linux-source fakeroot

mkdir ~/src
cd ~/src
tar xjvf /usr/src/linux-source-<version>.tar.bz2
cd linux-source-<version>

# Apply the changes to PROT_SOCK define in /include/net/sock.h

# Copy the kernel config file you are currently using
cp -vi /boot/config-`uname -r` .config

# Install ncurses libary, if you want to run menuconfig
apt-get install libncurses5 libncurses5-dev

# Run menuconfig (optional)
make menuconfig

# Define the number of threads you wanna use when compiling (should be <number CPU cores> - 1), e.g. for quad-core
export CONCURRENCY_LEVEL=3
# Now compile the custom kernel
fakeroot make-kpkg --initrd --append-to-version=custom kernel-image kernel-headers

# And wait a long long time

cd ..

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


systemd является заменой sysvinit, которая имеет возможность запускать демон с определенными возможностями. Опции возможности=, CapabilityBoundingSet= в systemd в.exec (5) manpage.


перенаправление портов имело для нас наибольший смысл, но мы столкнулись с проблемой, когда наше приложение разрешит url-адрес локально, который также необходимо перенаправить; (это означает, что вы вечеринка).

Это также позволит вам перенаправляться при доступе к url-адресу на локальном компьютере.

iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -A OUTPUT -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080

при запуске:

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

затем вы можете привязаться к порту, на который вы отправляете.


С systemd вам просто нужно немного изменить свой сервис, чтобы принять предварительно активированные сокеты.

вы можете позже использовать активация сокета systemd.

никаких возможностей, iptables или других трюков не требуется.

это содержимое соответствующих файлов systemd из этого примера простого python http server

httpd-true.service
[Unit]
Description=Httpd true 

[Service]
ExecStart=/usr/local/bin/httpd-true
User=subsonic

PrivateTmp=yes
httpd-true.socket
[Unit]
Description=HTTPD true

[Socket]
ListenStream=80

[Install]
WantedBy=default.target

почему-то никто не упоминает о снижении сети sysctl.протокол IPv4.ip_unprivileged_port_start к нужному вам значению. Пример: нам нужно привязать наше приложение к порту 443.

sysctl net.ipv4.ip_unprivileged_port_start=443

некоторые могут сказать, что существует потенциальная проблема безопасности: непривилегированные пользователи теперь могут привязываться к другим привилегированным портам (444-1024). Но вы можете легко решить эту проблему с помощью iptables, заблокировав другие порты:

iptables -I INPUT -p tcp --dport 444:1024 -j DROP
iptables -I INPUT -p udp --dport 444:1024 -j DROP

сравнению с другими методами. Этот метод:

  • С какой-то точки зрения (IMO) даже более безопасно, чем установка CAP_NET_BIND_SERVICE/setuid, так как приложение вообще не setuid, даже частично (возможности на самом деле). Например, чтобы поймать coredump приложения с поддержкой возможностей, вам нужно будет изменить sysctl fs.suid_dumpable (что приводит к другим потенциальным проблемам безопасности) Кроме того, когда Cap/suid установлен, каталог /proc/PID принадлежит root, поэтому ваш пользователь без root не будет иметь полной информации / контроля например, в запущенном процессе пользователь не сможет (в обычном случае) определить, какие соединения принадлежат приложению через /proc/PID/fd/ (netstat-aptn | grep PID).
  • имеет недостаток безопасности: в то время как ваше приложение (или любое приложение, которое использует порты 443-1024) по какой-то причине, другое приложение может взять порт. Но эта проблема также может быть применена к CAP/suid (если вы установите его на интерпретаторе, например java/nodejs) и iptables-redirect. Используйте метод systemd-socket, чтобы исключить это проблема. Используйте метод authbind, чтобы разрешить только специальную привязку пользователя.
  • не требует установки CAP / suid каждый раз при развертывании новой версии приложения.
  • не требует поддержки/модификации приложения, например метода systemd-socket.
  • не требует восстановления ядра (если запущенная версия поддерживает этот параметр sysctl)
  • не делает LD_PRELOAD как метод authbind / privbind, это может потенциально повлиять на производительность, безопасность, поведение (делает это? не проверял). В остальном authbind действительно гибкий и безопасный метод.
  • over-performs iptables REDIRECT/DNAT метод, так как он не требует преобразования адресов, отслеживания состояния соединения и т.д. Это заметно только на высоконагруженных системах.

в зависимости от ситуации я бы выбрал между sysctl, CAP, authbind и iptables-redirect. И это здорово, что у нас так много вариантов.


есть и djb пути. Вы можете использовать этот метод, чтобы запустить процесс как root, работающий на любом порту под tcpserver, затем он передаст управление процессом пользователю, которого вы укажете сразу после запуска процесса.

#!/bin/sh

UID=`id -u yourusername`
GID=`id -g yourusername`
exec tcpserver -u $UID -g $GID -RHl0 0 portnumber   /path/to/your/process &

подробнее: http://thedjbway.b0llix.net/daemontools/uidgid.html


поскольку OP-это просто разработка / тестирование, менее гладкие решения могут быть полезны:

setcap можно использовать в интерпретаторе скрипта для предоставления скриптам возможностей. Если setcaps на глобальном двоичном интерпретаторе неприемлемо, сделайте локальную копию двоичного файла (любой пользователь может) и получите root для setcap на этой копии. Python2 (по крайней мере) правильно работает с локальной копией интерпретатора в дереве разработки скриптов. Не требуется suid, чтобы пользователь root мог управлять тем, что возможности пользователи имеют доступ.

Если вам нужно отслеживать общесистемные обновления интерпретатора, используйте сценарий оболочки, как показано ниже, чтобы запустить сценарий:

#!/bin/sh
#
#  Watch for updates to the Python2 interpreter

PRG=python_net_raw
PRG_ORIG=/usr/bin/python2.7

cmp $PRG_ORIG $PRG || {
    echo ""
    echo "***** $PRG_ORIG has been updated *****"
    echo "Run the following commands to refresh $PRG:"
    echo ""
    echo "    $ cp $PRG_ORIG $PRG"
    echo "    # setcap cap_net_raw+ep $PRG"
    echo ""
    exit
}

./$PRG $*

использовать privbind утилита: позволяет непривилегированному приложению привязываться к зарезервированным портам.


я попробовал метод перенаправления iptables PREROUTING. В старых ядрах кажется, что этот тип правила не поддерживается для IPv6. Но, видимо, это теперь поддерживается в ip6tables В1.4.18 и ядра Linux версии 3.8.

Я также обнаружил, что предварительное перенаправление не работает для соединений, инициированных внутри машины. Чтобы работать для соединений с локальной машины, добавьте также правило вывода-см. iptables Port redirect не работает для localhost. Е. Г. что-то например:

iptables -t nat -I OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080

Я также обнаружил, что предварительная перенаправление также влияет на пересылаемые пакеты. То есть, если машина также пересылает пакеты между интерфейсами (например, если она действует как точка доступа Wi-Fi, подключенная к сети Ethernet), то правило iptables также будет перехватывать подключения подключенных клиентов к интернет-адресатам и перенаправлять их на машину. Это не то, что я хотел-я только хотел перенаправить соединения, которые были направлены на машину себя. Я обнаружил, что могу повлиять только на пакеты, адресованные коробке, добавив -m addrtype --dst-type LOCAL. Е. Г. что-то вроде:

iptables -A PREROUTING -t nat -p tcp --dport 80 -m addrtype --dst-type LOCAL -j REDIRECT --to-port 8080

еще одна возможность - использовать перенаправление портов TCP. Е. Г. используя socat:

socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080

однако одним из недостатков этого метода является то, что приложение, которое прослушивает порт 8080, не знает адреса источника входящих соединений (например, для ведения журнала или других целей идентификации).


ответ на 2015 / Sep:

ip6tables теперь поддерживает IPV6 NAT:http://www.netfilter.org/projects/iptables/files/changes-iptables-1.4.17.txt

вам понадобится ядро 3.7+

доказательство:

[09:09:23] root@X:~ ip6tables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REDIRECT   tcp      eth0   *       ::/0                 ::/0                 tcp dpt:80 redir ports 8080
    0     0 REDIRECT   tcp      eth0   *       ::/0                 ::/0                 tcp dpt:443 redir ports 1443

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 6148 packets, 534K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain POSTROUTING (policy ACCEPT 6148 packets, 534K bytes)
 pkts bytes target     prot opt in     out     source               destination