Docker: intercept outbound traffic and change ip:port to another container - linux

First of all, I wanna say that I don't have much experience in advanced networking on Linux.
A have a task to deploy our .deb packages in containers, and applications are mostly tunned for operating on localhost while being designed with the capability of operating onset of server machines (DB, application, client, etc), but since components of the app have been distributed between containers, I need to make it work together. The goal is to do it w/o any pre-setup sequences that change the IP address in configs for components since target IP is uncertain and IP alias in /etc/hosts may not solve the problem.
Could I somehow intercept outbound connection to localhost:5672 and forward it to, we say, 172.18.0.4:5672 with the ability to correctly receive incoming traffic from the resource we forwarded to? Can you give me some examples of the script?

Related

How can I create a firewall which allows me to make application based rules?

I do not trust anything, so I want to write my own firewall. I'm not satisfied with the application firewalls in Linux and Windows and the distro firewalls are not adequate for my purposes. I'm frustrated with distro firewalls, most of them like pfSense, OPN Sense, ipfire just seem to give illusion of firewall but all they do is packet filtering. I'm unable to block everything and only allow few websites with it, I have created a rule to block DNS requests, applied that rule and rebooted the firewall distro but it doesn't seem to have any effect. I either have to block everything or allow everything, both of which are undesirable. The sc*mbags seemed to have deliberately made the interface unintuitive to sell service, they claim their firewalls are free but made the interface obtuse, so that they can steal money by selling service.
I'm thinking of writing my own firewall, one of this will be an application which will run on the client system and the other would be standalone distro, both will run together to allow better management. The application on the client will create a special packet signed with the hash of the application, OS, etc and the intermediary firewall distro will check this hash and allow rules and policies to be created based on this hash. Does the TCP/IP protocol allow this?
I have searched the net for resources about network API on Linux, and there are three resources about writing my own firewall, two are questions here and one is netfilter. I don't know anything about TCP/IP protocol, so I don't know if I can use the packets made TCP/IP to achieve this or I have to creatively find a way to create a special packet.

Receive realtime data from phone

I am using an android app that streams real-time accelerometer data to the specified ip address of a server. I have written a "server" in C running on Linux which is running in VMware.
I am connected to the hotspot created by the Windows7(Host machine) running the VMware Workstation.
So my question is how do I connect the virtual-machine to same network as the hotspot so that I can get the phone and the "server" program on the same network and stream data to the server program?
I use VirtualBox, but I'm guessing the settings are very similar in VMWare Workstation.
You probably need to do one or both of these things:
1) Port Forwarding. If your app is hitting port 80 (or whatever port), you'll need to tell VMWare that any hits coming in to the host machine on that port get forwarded to the VM. Of course, your VM will have to be listening on that port. I'd suggest using a high port number (over 1024) to minimize conflicts, and avoid annoying root/admin issues using a low port number.
2) Hopefully that gets you there. If not, you may need to change the virtual adapter settings on the VM. NAT mode is a good first try. If not, there are other modes (bridged, internal, host-only) you can tinker with. (Not sure if VMWare uses different names)
That's probably all you need for the topology you describe -- Android device connected directly to the same subnet as the host machine. If not, perhaps your hotspot routes all client traffic to the gateway (i.e. out to the Internet), without allowing direct access to localhost. If so, maybe there are settings for that. If not, ngrok is your new best friend.
It is SUPER easy and allows you to tunnel traffic from anywhere on the Internet to a specific service running on your machine. This would sidestep some of the issues above.
If you want to take your Android device to another network (e.g. cell network), then ngrok is absolutely the way to go, particularly for development and prototyping. This lets you avoid issues with DNS, routing, firewalls, etc.

Hosting a web application on an ad-hoc network in linux

This is my first question on SO. Basically, I am attempting to create a sort of offline neighborhood forum. I have setup NodeBB to host a forum locally, but the problem is allowing users to connect. Eventually I plan to use a high-strength wireless router to broadcast an open network, and from there redirect all traffic to the local page. In the mean time, I was wondering if it would be possible to implement this with by means of an ad-hoc network. Broadcasting an ad-hoc network seems easy enough, but how might I redirect the traffic to the port running NodeBB? Any help or comments on the overall idea would be greatly appreciated.
By default, NodeBB listens on all network interfaces (0.0.0.0), so if you set up an ad-hoc network, anybody connected to your machine will be able to access it via MACHINE_IP:4567.
If you have your machine behind a NAT/Router, you'll have to forward port 4567 to your machine. Alternatively, you could translate requests from external port 80 to port 4567, though that is untested for NodeBB specifically.

Hostname discovery for all machines on a network

Problem: I am developing a graphical front end for a distributed CPU/GPU simulator. As this simulator utilizes MPI, it requires a hostfile detailing the hostnames for all computers being used on the network so that it knows what machines to distribute across. As the end users for my application are not computer scientists (and may not even be very computer literate), I can't expect them to know/find the hostnames of every computer on their network/cluster. I would like to programmatically perform this hostname discovery so that, upon application start-up, the user can see the available machines, and from those, pick the hosts they want to run on. If possible, I would like this solution to be cross platform but as the simulator currently contains some linux dependencies I can deal with a Linux only solution.
What I have tried so far: I tried utilizing the nmap package to discover hosts on a network with commands like nmap -sP <ip address range> using the ip address range for that local network. However, it only dumps the IP addresses for the hosts (not the host names) and I'm not sure how to translate these IP addresses into ssh hostnames (as MPI uses ssh for host discovery). Additionally, I used a similar approach with ping supplying the broadcast address and it returned nearly identical results.
I apologize for the broad nature of this question and the lack of code shown but I am not very experienced with network probing / programming and I am really not even sure where to start. I tried googling this but I was unable to find a suitable option (possibly because my lack of experience caused me to use improper terminology triggering improper results) My background is primarily in graphics and user interface programming, so this is a little beyond my comfort zone.
SSH doesn't care if it is given hostnames or IP addresses to connect to (not sure if this applies when there are host-specific configurations). Most MPI implementations don't care too, e.g. in Open MPI connection URIs addresses are all numeric, so a hostfile with IPs would be fine. HTTP servers on the other hand care because of the virtual hosting thing where many different sites resolve to the same IP address but the server is supplied the actual hostname via the Host HTTP header.
Unsolicited advice: finding hosts by ping is fine, but it doesn't guarantee that you have found machines, where SSH is running. You would better scan for systems with port 22 open that accept TCP connections:
$ nmap -oX -sT -p22 <ip range>
-oX produces XML output that can be easily parsed. -oG is also a nice format for automated parsing of the scan results. Also having SSH running doesn't necessarily mean that the user would be able to log into the system - for example it could be a network router or another remotely manageable device. One also has to take care of only showing machines where the user can log on without having to supply a password, e.g. with RSA/DSA public keys, otherwise starting an MPI job would be a really tedious task. You can test each host found with something like:
$ ssh -2 -o "PreferredAuthentications=gssapi-with-mic,hostbased,publickey" \
<host> hostname
This command basically excludes all interactive authentication methods. If connection succeeds, it will output the hostname of the remote machine. Otherwise you'd get a permission denied error and a non-zero exit code from the SSH client.

How can I develop using a local VM server without using URLs with ports in them?

I'm setting up a linux server in a VM for my development.
Previously I've had PHP, MySQL etc etc all installed locally on my Mac. Apart from being a security risk, it's a drag to maintain and keep up to date, and there's a risk that an OS upgrade will wipe part of your setup out as the changes you make are fairly non-standard.
Having the entire server contained within a VM makes it easily upgradable and portable between machines. It means I can have the same configuration as the destination server and with shared folders even if the VM gets corrupted my work is safe on the host machine.
Previously with the local installation I was able to develop on convenient URLs like http://site.dev. I'd quite like to carry this over to the VM way of development but I'm struggling to figure out how, if it's possible at all.
Here's the problem:
In Bridged mode, the VM is part of the same network as the host. This is great but I can't choose a fixed IP address as I may be joining other networks and that address may be taken already. I'd like a consistent way of addressing my VM.
In NAT mode I can't directly address the VM without using port forwarding. I can use http://site.dev if I use the hosts file to forward that to localhost and then localhost:8080 forwards to the vm:80. The trouble is I have to access http://site.dev:8080 which is inconvenient for URL construction.
Does anyone know a way around this? I'm using ubuntu server and virtualbox.
Thanks!
The answer is to define a separate host-only network adapter and use that for host->guest communication.
You can do this by powering down the guest and adding the adapter in the VM settings. Once that's done you can boot the guest again and configure the new network interface however suits you best. I chose a fixed IP address in an unused range.

Resources