How do I deploy code to hardware nodes that are all on seperate networks? - linux

This is an interesting problem I've been thinking about recently and have not come up with or found a solution that I find acceptable.
I'm playing with Raspberry Pi's and have 6 currently that I want to use throughout a few of my personal properties for surveillance purposes.
Making them work and sending video streams to my server is all easy, well and good - but how in the world do I deploy code updates to these "nodes" that are not on the same network, some are behind wi-fi networks that I don't have port forwarding access to also, so it's not like I can just post forward and SSH into them and run some .sh magic to update things.
The best I've come up with is using autossh to keep a constant, connection open to one of my servers through reverse ssh, and then ssh in to them through my parent server in parallel and running a .sh script on them when I want to update.. But this seems overly excessive and I'm sure there's some solution or platform out there that exists to solve this - how else do companies like Redbox or Nest for example update firmware on their systems remotely?

I'm actually doing something similar. I have Pi's deployed around the city that I live in. In order to not have to worry about port-forwarding and people changing their router configurations, I started using a service called Pagekite http://pagekite.net/
I'm not affiliated with them, but I can't say enough good things about the service and price. My Pi's are hooked up to screens that need to display certain things at certain times, and I'm able to VNC in very easily no matter where the Pi is to see what's currently playing. I can obviously just ssh in as well.
The following steps from my pi setup guide deal with installing pagekite and getting it to start on boot:
echo deb http://pagekite.net/pk/deb/ pagekite main | sudo tee -a /etc/apt/sources.list
sudo apt-key adv --recv-keys --keyserver keys.gnupg.net AED248B1C7B2CAC3
sudo apt-get update
sudo apt-get install pagekite
sudo leafpad /etc/pagekite.d/10_account.rc
Replace NAME.pagekite.me with the name of the kite
Replace YOURSECRET with whatever the secret is from the pagekite admin console
Remove the line “abort_not_configured” and the comment above it
sudo cp /etc/pagekite.d/80_sshd.rc.sample /etc/pagekite.d/80_sshd.rc
sudo invoke-rc.d pagekite restart
sudo reboot
This assumes you've made an account and setup a "kite"
I think you basically need a reliable reverse tunnel such as Pagekite, especially if you plan on expanding your network, as it will turn into a nightmare at a certain size. I believe I'm just going to keep a list of ssh usernames, ssh passwords, and pagekite addresses, then write a script that loops through them and rsync's my local directory with the new code to the remote directory on the pi.

Related

FortiClient headless linux cli - how to install and configure to handle certain IP ranges only or permit SSH

I am trying to configure the headless VPN only FortiClient on an AWS ubuntu 20.04 ec2 instance, and though I am able to connect to the target, I am then disconnected from the instance and cannot progress.
Setup:
wget http://cdn.software-mirrors.com/forticlientsslvpn_linux_4.4.2328.tar.gz
tar -xzvf forticlientsslvpn_linux_4.4.2328.tar.gz
cd ./forticlientsslvpn/64bit/helper
sudo ./setup.linux.sh
# Accept license
cd ..
./forticlientsslvpn_cli --server serveraddress:port --vpnuser username
# Enter password
##Connected!
At this stage, I am booted out of the instance and cannot reconnect (requiring a soft restart of the instance to gain access again)
I can see that there is a configuration file at forticlientsslvpn/64bit/helper/config but I cannot find any documentation describing what can be configured there or whether it is something I should be concerned with.
The CLI itself doesn't take any other options other than:
forticlientsslvpn_cli [--proxy proxyaddress:proxyport] --server vpnserveraddress:vpnport [--proxyuser proxyuser] [--vpnuser vpnuser] [--pkcs12 pkcs12path] [--keepalive]
I would like to either:
Preserve my original SSH connection (and any future connections) so I can develop within the VPN or;
Limit the VPN to only package traffic that is going to a specific IP range (CIDR block)
I have found three different methods for installing the client (sudo apt install forticlient, sudo apt install -y openfortivpn, see above) and cannot navigate through them. I have looked into FortiClientLinuxGuide and installed that tool but couldn't find out how to configure it as a VPN instead (or where to add the configuration). Similar experience with the second one.
This seems to be the only documentation about how to configure the CLI and its just the bear minimum How to setup and install SSLVPN.
This post seems to be having the same problem ssh-telnet-disconnects and the solution looks like it would work if only I knew how to set that configuration.
alternatively, I have looked up split tunnel configuration which looks like it would be ideal but cannot work out how I would set that up. The documentation is only via the GUI Enable-split-tunnel-feature

Serial port unavaliable arduino

Trying to upload a code to arduino, but whether in the Arduino IDE or Arduino Create, both return this erro while uploading. Running on Linux Tara(mint 19 cinnamon).
./opt/arduino-builder/arduino-builder -compile -core-api-version 10611 -hardware opt/arduino-builder/hardware -hardware ./opt/cores -tools opt/arduino-builder/tools -tools ./opt/tools -built-in-libraries opt/libraries/latest -logger humantags -fqbn arduino:avr:mega:cpu=atmega2560 -build-cache /tmp -build-path /tmp/716441957/build -verbose -libraries /tmp/716441957/custom -libraries /tmp/716441957/pinned /tmp/716441957/sketch_oct8a
Sketch uses 8280 bytes (3%) of program storage space. Maximum is 253952 bytes.
Global variables use 443 bytes (5%) of dynamic memory, leaving 7749 bytes for local variables. Maximum is 8192 bytes.
Programming with: Serial
Flashing with command:/home/jesus/.arduino-create/arduino/avrdude/6.3.0-arduino9/bin/avrdude -C/home/jesus/.arduino-create/arduino/avrdude/6.3.0-arduino9/etc/avrdude.conf -q -q -patmega2560 -cwiring -P/dev/ttyACM0 -b115200 -D -Uflash:w:/tmp/arduino-create-agent734074237/sketch_oct8a.hex:i
avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied
ioctl("TIOCMGET"): Inappropriate ioctl for device
ioctl("TIOCMGET"): Inappropriate ioctl for device
1#
First, check the port in your IDE. In Arduino tools->port
If the port is hidden or you can not move the cursor over this then run this commands in your terminal.If everything ok then skips this and follow the second part.
sudo apt-get install librxtx-java -y
sudo usermod -aG dialout $USER
sudo apt-get install gnome-system-tools
2#
After this again check the first method. If it is not working then run this commands
ls -l /dev/ttyACM*
sudo usermod -a -G dialout <username>
You probably have another program running which is already using this port.
You should close most other programs like putty or another serial monitor app.
Otherwise, try to reconnect the Arduino to the PC.
I know that these ideas below come from using a Teensy, but they may help you.
Sometimes there are the ACM* ports listed in the Arduino IDE. Try looking at the ser ports. I know when I am running my Teensy, sometimes I have them switched and need to select the correct one.
Also, from my experience with the Teensy, you might need to add a udev rule to allow permissions to access the port from non-root user. Here is the link that shows the udev file.
There is no direct way to solve this issue. In addition to it, you are not using an IDE. I will list the things you need to check, I am sure this will solve your problem.
I am not good at Linux environment so I will refer to applications names as window, you go the corresponding application in Linux.
Go to linux device manager and see for your arduino board. It should have proper naming like "arduino uno at port 3", then use the correct port in your command. If this name does not come properly then it means Driver is not available in your machine. So, go to step2.
Find the driver online and install it in your system, I am not sure about the support of linux with arduino, once it is done please repeat step1.
So, I conclude in short that you do not have the proper driver (which is strongly believe) or pointing the wrong port. I am not an expert with the udev rules, but it is definitely an issue you can experience with these kinds of micro-controllers.

What user will Ansible run my commands as?

Background
My question seems simple, but it gets more complex really fast.
Basically, I got really tired of maintaining my servers manually (screams in background) and I decided it was time to find a way to make being a server admin much more liveable. That's when I found Ansible. Great huh? Sure beats making bash scripts (louder scream) for everything I wanted to automate.
What's the problem?
I'm having a lot of trouble figuring out what user my Ansible playbook will run certain things as. I also need the ability to specify what user certain tasks will run as. Here are some specific use cases:
Cloning a repo as another user:
My purpose with this is it run my node.js webapp from another user, who we'll call bill (that can only use sudo to run a script that I made that starts the node server, as opposed to root or my user that can use sudo for all commands). To do this, I need the ability to have Ansible's git module clone my git repo as bill. How would I do that?
Knowing how Ansible will gain root:
As far as I understand, you can set what user Ansible will connect to the server you're maintaining by defining 'user' and the beginning of the playbook file. Here's what I don't understand: if I tell it to connect via my username, joe, and ask it to update a package via the apt module, how will it gain root? Sudo usually prompts me for my password, and I'd prefer keeping it that way (for security).
Final request
I've scoured the Ansible docs, done some (what I thought was thorough) Googling, and generally just tried to figure it out on my own, but this information continues to elude me.
I am very new to Ansible, and while it's mostly straight-forwards, I would benefit greatly if I could understand exactly how Ansible runs, on which users it runs, and how/where I can specify what user to use at different times.
Thank you tons in advance
You may find it useful to read the Hosts and Users section on Ansible's documentation site:
http://docs.ansible.com/playbooks_intro.html#hosts-and-users
In summary, ansible will run all commands in a playbook as the user specified in the remote_user variable (assuming you're using ansible >= 1.4, user before that). You can specify this variable on a per-task basis as well, in case a task needs to run as a certain user.
Use sudo: true in any playbook/task to use sudo to run it. Use the sudo_user variable to specify a user to sudo to if you don't want to use root.
In practice, I've found it easiest to run my playbook as a deploy user that has sudo privileges. I set up my SSH keys so I can SSH into any host as deploy without using a password. This means that I can run my playbook without using a password and even use sudo if I need to.
I use this same user to do things like cloning git repos and starting/stopping services. If a service needs to run as a lower-privileged user, I let the init script take care of that. A quick Google search for a node.js init.d script revealed this one for CentOS:
https://gist.github.com/nariyu/1211413
Doing things this way helps to keep it simple, which I like.
Hope that helps.
My 2 cents:
Ansible uses your local user (eg Mike) to ssh to the remote machine. (That required Mike to be able to ssh to the machine)
From there it can change to a remote user if needed
It can also sudo if needed and if Mike is allowed. If no user is specified then root will be selected via your ~/.ansible.cfg on your local machine.
If you supply a remote_user with the sudo param then like no.3 it will not use root but that user.
You can specify different situations and different users or sudo via the playbooks.
Playbook's define which roles will be run into each machine that belongs to the inventory selected.
I suggest you read Ansible best practices for some explanation on how to setup your infrastructure.
Oh and btw since you are not referring to a specific module that ansible uses and your question is not related to python, then I don't find any use your question having the python tag.
Just a note that Ansible>=1.9 uses privilege escalation commands so you can execute tasks and create resources as that secondary user if need be:
- name: Install software
shell: "curl -s get.dangerous_software.install | sudo bash"
become_user: root
https://ansible-docs.readthedocs.io/zh/stable-2.0/rst/become.html
I notice current answers are a bit old and suffering from link rot.
Ansible will SSH as your current user, by default:
https://docs.ansible.com/ansible/latest/user_guide/intro_getting_started.html#connecting-to-remote-nodes
Ansible communicates with remote machines over the SSH protocol. By default, Ansible uses native OpenSSH and connects to remote machines using your current user name, just as SSH does.
This can be overridden using:
passing the -u parameter at the command line
setting user information in your inventory file
setting user information in your configuration file
setting environment variables
But then you must ensure a route exists to SSH as that user. An approach to maintaining user-level ownership I see more often is become (root) and then to chown -R jdoe:jdoe /the/file/path.
In my 2.12 release of ansible I found the only way I could change the user was by specifying become: yes as an option at the play level. That way I am SSHing as the unprivileged, default, user. This user must have passwordless sudo enabled on the remote and is about the safest I could make my VPS. From this I could then switch to another user, with become_user, from an arbitrary command task.
Like this:
- name: Getting Started
gather_facts: false
hosts: all
become: yes # All tasks that follow will become root.
tasks:
- name: get the username running the deploy
command: echo $USER
become_user: trubuntu # From root we can switch to trubuntu.
If the user permitted SSH access to your remote is, say, victor, and not your current user, then remote_user: victor has a place at the play level, adjacent to become: yes.

Cannot connect to X server :0.0 with a Qt application

Compiling on Fedora 10.
I have just started my first qt GUI application. I used all the default settings.
Its just a simple form. It builds OK without any errors. But when I try and run the application. I get the following message:
Starting /home/rob/projects/qt/test1/test1/test1...
No protocol specified
test1: cannot connect to X server :0.0
Thanks for any advice,
The general causes for this are as follows:
DISPLAY not set in the environment.
Solution:
export DISPLAY=:0.0
./myQtCmdHere
( This one doesn't appear to be the one at fault though, as its saying which X display its trying to connect to. Also, its not always 0.0, but most of the time it is )
Non-Authorised User trying to run the X Application
Solution ( as X owning user, ie: yourself )
xhost +local:root # where root is the local user you want to grant access to.
Also, if you'd like your X server to be able to receive connection over TCP, these days you must almost always explicitly enable this. To test whether you're server is allowing remote TCP connections try:
telnet 127.0.0.1 6000
If telnet is able to connect, then your X server is listening. If it can't, then neither will any remote X application and you need to enable remote TCP connections on your server.
Adding to above answers.
I was in a similar situation while running tests for Code2Pdf at travis.
I solved the problem using xvfb-run. Quoting from the manpage,
xvfb-run is a wrapper for the Xvfb(1x) command which simplifies the task of running commands (typically an X client, or a script containing a list of clients to be run) within a virtual X server environment.
The script that I wrote was:
check_install_xvfb() { # check and install xvfb
if hash xvfb-run 2>/dev/null; then
:
else
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install xvfb
fi
}
check_install_xvfb
export DISPLAY=localhost:1.0
xvfb-run -a bash .misc/tests.sh
# .misc/tests.sh is script that runs unit tests. You can replace it with something suitable to you.
Please bear with my bash code style. I am a noob bash programmer.
Running the above script helped me.
You can see the failing build and passing build.
Hope it helps

DHCP overwrites Cisco VPN resolv.conf on Linux

I'm using an Ubuntu 8.04 (x86_64) machine to connect to my employer's Cisco VPN. (The client didn't compile out of the box, but I found patches to update the client to compile on kernels released in the last two years.) This all works great, until my DHCP client decides to renew its lease and updates /etc/resolv.conf, replacing the VPN-specific name servers with my general network servers.
Is there a good way to prevent my DHCP client from updating /etc/resolv.conf while my VPN is active?
If you are running without NetworkManager handling the connections, use the resolvconf package to act as an intermediary to programs tweaking /etc/resolv.conf: sudo apt-get install resolvconf
If you are using NetworkManager it will handle this for you, so get rid of the resolvconf package: sudo apt-get remove resolvconf
I found out about this when setting up vpnc on Ubuntu last week. A search for vpn resolv.conf on ubuntuforums.org has 250 results, many of which are very related!
If you are using the Ubuntu default with NetworkManager, try removing the CiscoVPN client and use the NetworkManager vpnc plugin to connect to the Cisco VPN. This should avoid all problems, since NetworkManager then knows about your VPN connection.
I would advice following the advice from #Sean, but if that fails for whatever reason, it should be possible to configure dhclient to not request DNS servers in /etc/dhcp3/dhclient.conf
chattr +i /etc/resolv.conf should work. ( -i to undo )
But the better thing is to configure your dhclient.conf:
https://calomel.org/dhclient.html
Look at superceding domain-name-servers, and domain-name.
Also look at "send hostname;"
If it works at your work place, you will have a cool hostname for your PC and not some weird name that DHCP servers assign.
vpnc seems to be doing the right thing for my employer's cisco concentrator. I jump on and off the vpn, and it seems to update everything smoothly.
The DHCPclient daemon can be told not to update resolv.conf with a command line switch. (-r I think, depending on the client)
That's less dynamic, because you'd have to restart/reconfigure DHCP when you connect, but not too hard. Similarly, you could just stop the service, but you might lose your IP in the meantime, so I wouldn't really recommend that.
Alternatively, you could run the dhcpclient from within a cron job, adding the appropriate process checks.
This problem is much more noticeable on networks with low DHCP lease ages. There is a bug filed in Ubuntu's dhcp3 package launchpad:
https://bugs.launchpad.net/ubuntu/+source/dhcp3/+bug/90681
Which includes this patch in the description:
--- /sbin/dhclient-script.orig 2007-03-08 19:19:56.000000000 +0000
+++ /sbin/dhclient-script 2007-03-08 19:19:46.000000000 +0000
## -13,6 +13,10 ##
# The alias handling in here probably still sucks. -mdz
make_resolv_conf() {
+ # don't overwrite resolv.conf at RENEW time, since a VPN/PPTP tunnel may
+ # have updated it with remote DNS servers
+ [ "$reason" = "RENEW" ] && return
+
if [ -n "$new_domain_name" -o -n "$new_domain_name_servers" ]; then
# Find out whether we are going to mount / rw
exec 9>&0 </etc/fstab
This change to /sbin/dhcp-script stops DHCP client from overwriting /etc/resolv.conf when it renews its lease.

Resources