I write a python telnet client to communicate with a server through telnet. However, many people tell me that it's no secure. How can I convert it to ssh? Should I need to totally rewrite my program?
Just create a TCP tunnel via SSH and relay all the data through there, no need to reinvent the wheel. You can find examples in SSH docs under TCP tunneling (man ssh for instance).
But if you really want to rewrite it, then check out paramiko project.
While Telnet is insecure, it's essentially just a serial console over a network, which makes it easy to code for. SSH is much, much more complex. There's encryption, authentication, negotiation, etc to do. And it's very easy to get wrong in spectacular fashion.
There's nothing wrong with Telnet per se, but if you can change things over the network - and it's not a private network - you're opening yourself up for trouble.
Assuming this is running on a computer, why not restrict the server to localhost? Then ssh into the computer and telnet to localhost? All the security with minimal hassle.
Use one of these libraries in your Python application to talk to the SSHD daemon on the server:
http://wiki.python.org/moin/SecureShell
You'll want to look at something that will help you set up SSHD in a secure manner like this:
http://www.linuxjournal.com/article/8759
You will also need to ensure that you update the SSHD daemon regularly and make use of keys and strong, rotating passwords. All this should be standard for a telnet application too, but due to the lack of transport level encryption, you really shouldn't be using telnet for anything.
Related
I have a Solaris 10 system, with Python 2.6.4, and I have to retrieve the files via the SFTP protocol, from the server, which does not allow the SSH logging in, i.e. only SFTP with RSA key is allowed. Could anyone please tell me:
is this possible at all?
is this possible with the above version of Python, or I need to upgrade it to 2.7.* work with the latest version of Twisted?
I have found this treat with the relevant information: twisted conch filetransfer
And this one: Python Twisted: twisted conch filetransfer verifyHostKey
But it is said there that Twisted first creates the SSH channel, and then establishes SFTP on top of it (forgive me for my possible misunderstanding and/or illiteracy), from the Twisted documentation:
Conch also provides an endpoint that is initialized with an already established SSH connection. This endpoint just opens a new channel on the existing connection and launches a command in that.
Will the same approach work in case you can not logging in via SSH? I.e. might it be possible to create an SSH channel if terminal SSH logging in is forbidden?
Are there any other approaches except Paramico, any other libraries that can help me in case of "No" to the above questions?
I know nothing about "Twisted". But I believe that you just have a terminology problem.
which does not allow the SSH logging in, i.e. only SFTP with RSA key is allowed
The above is nonsense. You cannot allow SFTP, but disallow SSH, because as you have already found in Twisted documentation, SFTP runs on top of SSH (this is true in general, that's nothing Twisted-specific).
What your server most probably really "does not allow" is "shell" access. That's not the same as as SSH. So the server allows SSH, allows SFTP, but does not allow shell.
I need to write a python script which connects to the host over SSH and then somehow connects to a service sitting on localhost and performs a little interactive session.
What first came to mind is to use Paramiko to do a local port forwarding and then use Pythons's sockets library to communicate with the service.
But working with Paramiko was quite a challenge and I haven't figured out how to fix some issues.
So I switched to pxssh and used just simple scenario:
conn.sendline('telnet {} {}'.format('localhost', port)
conn.expect('PASSWORD:')
conn.sendline(password)
...
But that telnet thing really bothers me.
And I think it's possible to establish SSH connection in such a manner that from Python's code prospective I just do data = open('somefile').read() which actually opens a somefile on a remote host and all traffic is being encrypted because of SSH.
I would like to make HTTP requests over SSH tunnels using Twisted. I have seen examples of using Twisted to set up SSH local port forwarding, but that's not what I am after.
Instead, it seems to me it should be possible using Twisted to wrap the HTTP traffic inside SSH tunnel directly - ie. without having to set up Twisted to listen on a local port for forwarding traffic.
I've checked how Twisted Conch command-line script does the local port forwarding, in conch.ssh.forwarding. Should that be somehow integrated with a HTTP client? Or, on the other hand, I've read that SSHChannel supports twisted.internet.interfaces.ITransport interface, so it could be given to Protocols to run them over the secure connection? Then there's the new-ish endpoints API in Twisted: I wonder if an endpoint for tunneling traffic from the ssh server onwards would make sense?
Or something else?
I wonder if an endpoint for tunneling traffic from the ssh server onwards would make sense?
It would make a lot of sense.
There is an endpoint that connects a protocol to the stdio of a command running remotely using Conch - twisted.conch.endpoints.SSHCommandClientEndpoint. And development has started (but stalled, it seems) on an endpoint for connecting a protocol to a remote subsystem (eg sftp) using Conch. An endpoint for connecting to a remote address over a tunneled connection using Conch would make a great addition.
The branch which begins to implement SSHSubsystemClientEndpoint might be a useful thing to look at to get an idea of what is involved in writing this new endpoint. There may also be useful refactorings started in that branch that make it easier to add new endpoints like this (since the branch adds exactly the 2nd conch endpoint and probably had to do some work to make some code from the 1st conch endpoint more easily re-usable).
I'm writing a Python script which connects to remote hosts over a (super complicated) SOCKS/SSL tunnel. I am able to establish connections to IPs in a remote intranet on any port.
What I'm hoping to do is set up this python script to use IP addresses in the local loopback range (127.0.x.x) to become (maybe with the help of the hosts file) a 'replica' of the remote systems, and hence enable me to use applications which don't support proxies. The problem is that I don't always know what ports they're trying to connect to. It seems the only way to work this out is to bind sockets to all 65536 ports, which seems a little crazy. So two questions:
Is it crazy? Can I just set up a python list of sockets from 1-65536?
Or is there a better way I should be doing this? Can I monitor connections to an IP somehow and bind the ports just before they're needed?
I want to avoid using too much platform-dependent or non-python code if possible.
EDIT: To clarify, I'm only writing the client here - I have no control over the server. Believe me, if I had control over the server side of it I would not be doing it with SOCKS/SSL/CRAM :)
What about going lower level and interfacing a library designed for network analyzers like pycap?
This way you could detect all connection attempts and find the ports that you need to expose or may be you can just route the packets directly assuming the library in addition to packet detection can also do packet injection (pypcap page says this feature is experimental).
This would IMO make sense in python only for slow applications however...
Pycap seems to be developed for linux, but the core capturing is done by libpcap and for windows there is a similar library winpcap.
Matt,
If using windows your best shot is something like OpenVPN over the tunnel. OpenVPN requires only one TCP port/stream and gives you a pair of virtual interfaces with full connectivity.
[updated]
It may be possible using a TUN/TAP driver on the client side. See this unix version for ideas.
Overview:
I have a device sitting on a local network to a computer that is sitting on an outside network. I would like to create a software program that allows me to seamlessly connect to the device from a computer on a different network. For purposes of this question, I've created a picture to help describe the network flow. What I need help with is what python packages I would need to develop the solution for this problem.
Details:
I have a computer MYPC (IP address 192.168.0.168) that is attached to the internet running through a proxy server (ROUTER1). I have full control over MYPC's environment, which is running Linux.
I have a second computer SOMESERVER (IP address 192.168.1.168) that is attached to the internet running through a proxy server (ROUTER2). In addition, SOMESERVER (IP address 10.0.0.159) is also attached to a local network (LOCAL). SOMESERVER is running windows. I have very limited control with SOMESERVER: I am able to send an executable to SOMESERVER that can run once before it is removed. I do not know the internet/world IP address of the ROUTER2 initially.
I have a device (DEVICE1) attached to SOMESERVER through LOCAL (IP address: 10.0.0.157).
I have another device (DEVICE2) attached to SOMESERVER through LOCAL (IP address: 10.0.0.158). DEVICE(x) runs linux. I have python on DEVICE(x) and I could install a pure python package if I needed to. However, I do not have the ability to compile for DEVICE(x).
I can connect between SOMESERVER and MYPC through the internet using SSH over ROUTER1 and ROUTER2. I can connect between SOMESERVER and DEVICE1 through the local network (LOCAL) using Telnet. I can connect between SOMESERVER and DEVICE2 through the local network (LOCAL) using Telnet.
I want to send a program to SOMESERVER that allows me seamless access over SSH and Telnet to DEVICE1 and DEVICE2 from MYPC. In addition, I want that program to be running python.
Here's a picture that helps explain the above problem:
Solution:
What I think I want is as follows. I need help with the details and what packages I might need to make it happen.
Part 1: The Dial Home Client and Server
Create a "dial home" server program (DIAL_HOME_SERVER) for MYPC which listens for any one dialing home and then will "dial into" any SOMESERVER that "dials home" using SSH.
Create a "dial home" client program (DIAL_HOME_CLIENT) for SOMESERVER which is downloaded as part of a package
Part 2: The Proxy Server
Create a ssh to telnet proxy server program (PROXY_SERVER) for SOMESERVER which listens for connections from MYPC and funnels them into a telnet connection to DEVICE(x).
Thanks to Greg Hewgill, it sounds like I can use Paramiko to pull together the PROXY_SERVER code on SOMESERVER. It appears that Paramiko also requires PyCryto, and the Windows binary for it can be found here.
Future Robustness
At a future date, the telnet connection will be replaced with an SSH client (dropbox on DEVICE(x)).
In Closing
I think the above will allow MYPC to connect "seamlessly", but the details of how to put together these programs is unknown to me. I already know how to package up a python program using Innosetup and/or py2exe. What I'd love to see is links pointing to different pieces of the solution so I can pull it all together. And then I can post it.
Thanks in advance!
I have to admit that I didn't quite follow all of your description, especially the "dial home" client/server part. However, your diagram seems sufficient for understanding.
Set up port forwarding on "router2" that forwards the incoming SSH port to your Windows server.
Write a Python program (you will probably find paramiko helpful) that runs on your Windows server, listens for SSH connections, and opens a telnet connection to one of your devices on the back end.
That seems sufficient to me. If you've got weird restrictions on the Windows server about only being able to run an executable once before it is deleted, that seems like another problem to solve that doesn't really relate to this tunnelling problem.