Переброс MySQL с одного порта на другой, в пределах одной машины
Итак, для начала попробуем сделать локальный проброс, то есть, чтобы при подключении к порту 33060 нам в реальности откликался 3306 порт, по которому работает MySQL.
Для тестов нам понадобится telnet:
apt-get install -y telnet
Итак, убедимся, что MySQL работает на 3306 порту:
netstat -lnpt | grep 3306
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 4667/mysqld
Попробуем подключиться к MySQL посредством telnet:
telnet 127.0.0.1 3306
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
?
5.0.51a-24+lenny4,X!6,zD$',5se"tHHp|?bSC
Теперь подключим к фаерволлу вот такое правило, которое перебросит все запросы с 33060 порта на 3306 посредством цели REDIRECT (которая делает примерно следующее - "It redirects the packet to the machine itself by changing the destination IP to the primary address of the incoming interface"):
iptables -t nat -I OUTPUT --src 0/0 --dst 127.0.0.1 -p tcp --dport 33060 -j REDIRECT --to-ports 3306
Теперь проверим телнетом:
telnet 127.0.0.1 33060Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
?
5.0.51a-24+lenny4-KDSV4@(C,WoGTPv"@\/sv
Визуально, все работает, но будет ли работать mysql клиент?
Еще как будет, смотрим:
mysql --host=127.0.0.1 -uroot -pyour_password --port 33060 -e 'show databases;;'
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
+--------------------+
Переброс запросов к локалхосту на 3306 порт на удаленный сервер
Итак, теперь нам для тестов нужна еще одна машина с mysql клиентов и telnet:
apt-get install -y telnet
На первой же машине (с MySQL) нужно открыть MySQL наружу, чтобы он слушал внешний интерфейс:
vi /etc/mysql/my.cnf
И в блоке mysqld сделать следующую правку:
bind-address = 0.0.0.0
И перезаупстить сервер:
/etc/init.d/mysql restart
Теперь на второй машине-клиенте забрасываем весь трафик выходящий с интерфейса localhost на внешний сервер:
iptables -t nat -A OUTPUT -p tcp --dport 3306 -j DNAT --to ext.ernal.ip.addr:3306
После часов извращений (убрав -o lo и подключаясь не к локалхосту, а к внешнему IP клиент машину) я добился того, что:
telnet ext.ernal.ip.addr
Trying ext.ernal.ip.addr...
Connected to ext.ernal.ip.addr.
Escape character is '^]'.
dHost 'xxxx' is not allowed to connect to this MySQL serverConnection closed by foreign host.
Но команда, которая может завернуть обращения к localhost наружу по-прежнему упорно не работает:
iptables -t nat -A OUTPUT -p tcp -o lo --dport 3306 -j DNAT --to ip_of_server_with_mysql:3306
У кого есть идеи? Все машины Debian Lenny 5, а также тестил на 2.6.33.
Update:
Работать это не будет принципиально, вот такой вот iptables!
По материалам:
1. http://forums.cpanel.net/f5/iptables-redirect-internal-port-remote-mysql-98333.html (рекомендуют NAT)
2. http://ubuntuforums.org/showthread.php?t=1436579 (попытки применить NAT)
3. http://www.linuxquestions.org/questions/showthread.php?p=3909624#post3909624 (еще немного по iptables)
4. http://forum.slicehost.com/comments.php?DiscussionID=4647 (готовое решение!)
5. http://wiki.debian.org/Firewalls-local-port-redirection (примеры порт редиректа! готовые!)
6. http://www.linuxquestions.org/questions/linux-networking-3/iptables-how-to-redirect-locally-generated-packets-to-a-remote-server-797173/
7. http://www.experts-exchange.com/Networking/Linux_Networking/Q_22862486.html (проблема DNAT + loopback)
8. http://lists.netfilter.org/pipermail/netfilter/2005-April/059765.html (пару слов про необходимость CONFIG_IP_NF_NAT_LOCAL)
9. Ссылка на "как это сделать через iproute2": http://www.listware.net/201007/debian-user/27927-iptables-localhost-redirect.html
http://highloaded.blogspot.com/2010/02/mysql-socketa-localhost-tcp.html
ReplyDeleteВариант, но число патчей на хостинге уже стремится к страшным числам, еще один я не хочу :)
ReplyDeleteа по другому никак =)
ReplyDeleteСпосибо товарищ за ваш пост. А то я чуть с ума не сошел. Сижу тут больной, с температурой 38, и поставили мне ту же задачу.
ReplyDeleteПробую очевидное - не получается. Ничего понять не могу... и так пробовал, и эдтак. И на другом серваке попробовал.. нифига.
Стал гуглить и наткнулся на ваш пост.
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteПриветствую, вот может Вам поможет, мне лично помогло для решения своей задачи.
ReplyDeletehttp://www.geekzone.co.nz/forums.asp?forumid=46&topicid=87441
YourIP=127.0.0.1
YourExternalIP=192.168.10.10
YourPort=12345
TargetIP=203.97.30.147
TargetPort=80
iptables -t nat -F
iptables -t nat -A PREROUTING --dst $YourIP -p tcp --dport $YourPort -j DNAT --to-destination $TargetIP:$TargetPort
iptables -t nat -A POSTROUTING -p tcp --dst $TargetIP --dport $TargetPort -j SNAT --to-source $YourExternalIP
iptables -t nat -A OUTPUT --dst $YourIP -p tcp --dport $YourPort -j DNAT --to-destination $TargetIP:$TargetPort
P.S Не забудьте выполнить sysctl -w net.ipv4.conf.all.route_localnet=1. Проверял на Centos 7.
Крутейше!!! Спасибо что поделились!
Delete