
أنفاق SSH إلى الخادم البعيد.
|CircleCI| |AppVeyor| |readthedocs| |coveralls| |version|
|pyversions| |license|
المؤلف: Pahaz_
المستودع: https://github.com/pahaz/sshtunnel/
مستوحى من https://github.com/jmagnusson/bgtunnel، والذي لا يعمل على ويندوز.
انظر أيضًا: https://github.com/paramiko/paramiko/blob/master/demos/forward.py
paramiko_sshtunnel_ متاح على PyPI، لذا يمكنك تشغيل:
::
pip install sshtunnel
أو ::
easy_install sshtunnel
أو ::
conda install -c conda-forge sshtunnel
لتثبيته في بيئتك.
لتثبيته من المصدر، قم باستنساخ _ ثم تشغيل::
المستودع <https://github.com/pahaz/sshtunnel>python setup.py install
لتشغيل الاختبارات، تحتاج أولاً إلى
tox <https://testrun.org/tox/latest/>_ ثم تشغيل::
python setup.py test
أحد السيناريوهات النموذجية التي يكون فيها sshtunnel مفيدًا موضح في الشكل
أدناه. قد يحتاج المستخدم إلى الاتصال بمنفذ خادم بعيد (مثل 8080)
حيث لا يمكن الوصول إلا إلى منفذ SSH (عادةً المنفذ 22). ::
----------------------------------------------------------------------
|
-------------+ | +----------+
محلي | | | بعيد | :22 SSH
عميل | <== SSH ========> | خادم | :8080 خدمة ويب
-------------+ | +----------+
|
جدار ناري (المنفذ 22 فقط مفتوح)
----------------------------------------------------------------------
شكل1: كيفية الاتصال بخدمة محجوبة بواسطة جدار ناري عبر نفق SSH.
إذا كان مسموحًا به من قبل خادم SSH، فمن الممكن أيضًا الوصول إلى خادم خاص
(من منظور الخادم البعيد) غير مرئي مباشرة من الخارج
(من منظور العميل المحلي). ::
----------------------------------------------------------------------
|
-------------+ | +----------+ +---------
محلي | | | بعيد | | خاص
عميل | <== SSH ========> | خادم | <== محلي ==> | خادم
-------------+ | +----------+ +---------
|
جدار ناري (المنفذ 443 فقط مفتوح)
----------------------------------------------------------------------
شكل2: كيفية الاتصال بـ الخادم الخاص عبر نفق SSH.
تسمح واجهة برمجة التطبيقات إما بتهيئة النفق وتشغيله أو استخدام سياق with
والذي سيتولى تشغيل وإيقاف النفق:
الكود المقابل للشكل1 أعلاه، بافتراض أن عنوان الخادم البعيد هو
pahaz.urfuclub.ru، مصادقة بكلمة مرور ومنفذ ربط محلي معين عشوائيًا.
.. code-block:: python
from sshtunnel import SSHTunnelForwarder
server = SSHTunnelForwarder(
'alfa.8iq.dev',
ssh_username="pahaz",
ssh_password="secret",
remote_bind_address=('127.0.0.1', 8080)
)
server.start()
print(server.local_bind_port) # يظهر المنفذ المحلي المعين
# العمل مع `الخدمة السرية` عبر `server.local_bind_port`.
server.stop()
مثال لإعادة توجيه المنفذ إلى خادم خاص لا يمكن الوصول إليه مباشرة، بافتراض مصادقة بمفتاح خاص محمي بكلمة مرور، وخدمة SSH للخادم البعيد تستمع على المنفذ 443 وهذا المنفذ مفتوح في جدار الناري (شكل2):
.. code-block:: python
import paramiko
import sshtunnel
with sshtunnel.open_tunnel(
(REMOTE_SERVER_IP, 443),
ssh_username="",
ssh_pkey="/var/ssh/rsa_key",
ssh_private_key_password="secret",
remote_bind_address=(PRIVATE_SERVER_IP, 22),
local_bind_address=('0.0.0.0', 10022)
) as tunnel:
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('127.0.0.1', 10022)
# القيام ببعض العمليات مع جلسة العميل
client.close()
print('انتهى!')
مثال لإعادة توجيه المنفذ لمنفذ MySQL المحلي لـ Vagrant:
.. code-block:: python
from sshtunnel import open_tunnel
from time import sleep
with open_tunnel(
('localhost', 2222),
ssh_username="vagrant",
ssh_password="vagrant",
remote_bind_address=('127.0.0.1', 3306)
) as server:
print(server.local_bind_port)
while True:
# اضغط Ctrl-C للإيقاف
sleep(1)
print('انتهى!')
أو ببساطة باستخدام واجهة سطر الأوامر:
.. code-block:: console
(bash)$ python -m sshtunnel -U vagrant -P vagrant -L :3306 -R 127.0.0.1:3306 -p 2222 localhost
فتح جلسة SSH عبر نفقين. سيتم تحويل نقل SSH والأنفاق إلى خلفية، مما لن ينتظر توقف الاتصالات عند الإغلاق.
.. code-block:: python
import sshtunnel
from paramiko import SSHClient
with sshtunnel.open_tunnel(
ssh_address_or_host=('GW1_ip', 20022),
remote_bind_address=('GW2_ip', 22),
) as tunnel1:
print('تم الاتصال بـ tunnel1 (GW1_ip:GW1_port) بنجاح...')
with sshtunnel.open_tunnel(
ssh_address_or_host=('localhost', tunnel1.local_bind_port),
remote_bind_address=('target_ip', 22),
ssh_username='GW2_user',
ssh_password='GW2_pwd',
) as tunnel2:
print('تم الاتصال بـ tunnel2 (GW2_ip:GW2_port) بنجاح...')
with SSHClient() as ssh:
ssh.connect('localhost',
port=tunnel2.local_bind_port,
username='target_user',
password='target_pwd',
)
ssh.exec_command(...)
::
$ sshtunnel --help
usage: sshtunnel [-h] [-U SSH_USERNAME] [-p SSH_PORT] [-P SSH_PASSWORD] -R
IP:PORT [IP:PORT ...] [-L [IP:PORT ...]] [-k SSH_HOST_KEY]
[-K KEY_FILE] [-S KEY_PASSWORD] [-t] [-v] [-V] [-x IP:PORT]
[-c SSH_CONFIG_FILE] [-z] [-n] [-d [FOLDER ...]]
ssh_address
أدوات نفق SSH بأكواد بيثون نقية
الإصدار 0.4.0
مواضع المعاملات:
ssh_address عنوان IP لخادم SSH (البوابة لأنفاق SSH)
يتم تعيينه بـ "-- ssh_address" إذا كان مباشرة بعد -R أو -L
الخيارات:
-h, --help أظهر رسالة المساعدة هذه واخرج
-U SSH_USERNAME, --username SSH_USERNAME
اسم مستخدم حساب خادم SSH
-p SSH_PORT, --server_port SSH_PORT
منفذ TCP لخادم SSH (الافتراضي: 22)
-P SSH_PASSWORD, --password SSH_PASSWORD
كلمة مرور حساب خادم SSH
-R IP:PORT [IP:PORT ...], --remote_bind_address IP:PORT [IP:PORT ...]
تسلسل عنوان الربط البعيد: ip_1:port_1 ip_2:port_2 ... ip_n:port_n
مكافئ لـ ssh -Lxxxx:IP_ADDRESS:PORT
إذا تم حذف المنفذ، افتراضيًا إلى 22.
مثال: -R 10.10.10.10: 10.10.10.10:5900
-L [IP:PORT ...], --local_bind_address [IP:PORT ...]
تسلسل عنوان الربط المحلي: ip_1:port_1 ip_2:port_2 ... ip_n:port_n
يمكن للعناصر أيضًا أن تكون نطاقات صوك صالحة لنظام يونكس:
/tmp/foo.sock /tmp/bar.sock ... /tmp/baz.sock
مكافئ لـ ssh -LPORT:xxxxxxxxx:xxxx، حيث يكون عنوان IP المحلي اختياريًا.
افتراضيًا سيستمع على جميع الواجهات (0.0.0.0) ويختار منفذًا عشوائيًا.
مثال: -L :40000
-k SSH_HOST_KEY, --ssh_host_key SSH_HOST_KEY
مفتاح المضيف للبوابة
-K KEY_FILE, --private_key_file KEY_FILE
ملف المفتاح الخاص RSA/DSS/ECDSA
-S KEY_PASSWORD, --private_key_password KEY_PASSWORD
كلمة مرور المفتاح الخاص RSA/DSS/ECDSA
-t, --threaded السماح باتصالات متزامنة لكل نفق
-v, --verbose زيادة دقة إخراج الرسائل (الافتراضي: ERROR)
-V, --version إظهار رقم الإصدار والخروج
-x IP:PORT, --proxy IP:PORT
عنوان IP ومنفذ وكل SSH للوجهة
-c SSH_CONFIG_FILE, --config SSH_CONFIG_FILE
ملف تكوين SSH، افتراضيًا إلى ~/.ssh/config
-z, --compress طلب ضغط من الخادم عبر نقل SSH
-n, --noagent تعطيل البحث عن المفاتيح من وكيل SSH
-d [FOLDER ...], --host_pkey_directories [FOLDER ...]
قائمة الدلائل التي قد توجد فيها مفاتيح SSH (بتنسيق `id_*`)
.. _Pahaz: https://github.com/pahaz
.. _sshtunnel: https://pypi.python.org/pypi/sshtunnel
.. paramiko: http://www.paramiko.org/
.. |CircleCI| image:: https://circleci.com/gh/pahaz/sshtunnel.svg?style=svg
:target: https://circleci.com/gh/pahaz/sshtunnel
.. |AppVeyor| image:: https://ci.appveyor.com/api/projects/status/oxg1vx2ycmnw3xr9?svg=true&passingText=Windows%20-%20OK&failingText=Windows%20-%20Fail
:target: https://ci.appveyor.com/project/pahaz/sshtunnel
.. |readthedocs| image:: https://readthedocs.org/projects/sshtunnel/badge/?version=latest
:target: http://sshtunnel.readthedocs.io/en/latest/?badge=latest
:alt: حالة التوثيق
.. |coveralls| image:: https://coveralls.io/repos/github/pahaz/sshtunnel/badge.svg?branch=master
:target: https://coveralls.io/github/pahaz/sshtunnel?branch=master
.. |pyversions| image:: https://img.shields.io/pypi/pyversions/sshtunnel.svg
.. |version| image:: https://img.shields.io/pypi/v/sshtunnel.svg
:target: sshtunnel
.. |license| image:: https://img.shields.io/pypi/l/sshtunnel.svg
:target: https://github.com/pahaz/sshtunnel/blob/master/LICENSE