Unable to SSH in AWS - linux

I am facing a strange issue. Currently I am working over deployment and configuration of few services over AWS over multiple instances. I have been creating multiple EC2 Instances and deploying required services over it. To start my jars, I have written a script. Ubuntu asks me to broaden the permissions for running the script. Since it is a test server, I have been granting 777 permissions to the ubuntu user as below -
Ubuntu User Home Path = /home/ubuntu, Script Path = /home/ubuntu/IASQueueBuilder/scripts
I am not sure what exactly goes wrong but after few mins, I get kicked out of ssh and then I can never ssh again to that instance.
To troubleshoot this, I have created a new instance and this time just gave 777 permissions to the script I have to run and nothing strange happens.
Can anyone help me figure the reasoning behind this? I have done some homework and I could see there are multiple issues with ssh to AWS Instances. Few are as below -
https://forums.aws.amazon.com/message.jspa?messageID=765025
https://forums.aws.amazon.com/message.jspa?messageID=246274

It looks to me like you've messed up the /home/user/.ssh directory permissions, that's why you can't access your instance now. The .ssh directory should have 700 permissions. You can fix this and access your instance by doing the following:
Stop your instance
Detach the volume
Create new instance
Attach the volume from your problematic instance to the new instance
Mount it on /mnt/something or where ever you want so that you could
have access to it
Manually fix the permissions of .ssh directory. One you're done, detach the volume from instance #2 and attach it to your main instance.
Also, consider snapshot-ing your instances, or at least the one with important data. It never hurts to have a backup.

Related

Executable to launch an Azure Virtual Machine

I need to create tools so that a non-experienced/non-technical users can use (which means connect and start/stop) a Virtual machine on Azure. For connection, the RDP connection is doing a good enough job and is easy to take a hand-on. On the other side, to start / stop a virtual machine you normally need to access to the Azure portal which (on top of being not straightforward for a non-technical user) causes some access policy problems. One option could be to just let the virtual machine always "on" but then we are billed for 100% of time even though the user only needs it for a couple hours a week.
That's why I investigated the possibility to create a script that could be put into an executable file that would launch automatically the virtual machine by just clicking the exec. I have already seen this stackoverflow question :
Start azure virtual machine without azure portal
which suggests to create an Azure PowerShell script that would start the virtual machine. Only problem is that launching a powershell script is out of the technical level of the person who would use it. On top of that, there is a need to install Azure add-on for powershell (if I understand correctly) which would not be possible depending on the machine and the rights the user have on it.
So my question : Do you have any idea on how I could make a simple program (in the form for example of an executable that would run on any machine without any dependency) that would start an azure virtual machine ?
One solution I thought about but it seemed very complicated : create a "super low cost" virtual machine that would be on 100% of time and just create an exec that instruct this VM to start the other virtual machine on demand ?
Thanks for your help
I have a problem with the idea that a powershell script is outside of the scope of a user that can run an exe file. If built properly, a ps1 should just be a double-click, exactly like an exe.
Aside from that, you have a couple hurdles to look at.
Your user can't have access to the resources that they need to interact with.
This can be done by passing custom PScredential objects through the script and pulling the credentials from a file. You would build the credential file with ConvertFrom-SecureString and then import it in with CovertTo-SecureString. The biggest problem with this is that if the user can see where that file is stored, they could potentially write a script to access that file and gain privileged access.
Your user doesn't have permission to run the powershell resources needed to execute the script. For this, you'd need to build in runas permission on the script, and I think creating an exe might be the best avenue for that. Although you could have the initial script call another shell with elevated permissions and work through that.
There are tools out there like PowerGUI, that will compile a ps1 file into an exe format. A properly compiled and secure exe file would hide the scripts that call out to secure string files and also allow for custom runas permissions built into the program.

Linux AWS immediately down by rm -rf /*

I was working to delete a single file.
I accidentally typed /* and all files are gone. It's okay since I have my backups but the main problem is that I'm not able to login into aws ec2 instance. Can anyone help me out?
You won't be able to login into the instance because you tore it down with that command. You should login to the EC2 dashboard (or use the aws-console) and terminate the instance and / or start a new one from the image backup you may have.

What is the correct way to run an nginx docker container in OpenShift?

RedHat OpenShift runs docker containers as random user IDs.
This works fine for some containers, but the NGINX container requires file permissions to be set to world read/write/execute in order to work.
Is there a more correct way to build/run a container for use with OpenShift?
For example, does OpenShift provide any kind of process ownership groups or rules?
Here is the nginx image I pull down, and the chmod command we currently run to make it work in OpenShift.
registry-nginxinc.rhcloud.com/nginx/rhel7-nginx:1.9.2
RUN chmod -R 777 /var/log/nginx /var/cache/nginx/ \
&& chmod -R 777 /var/run \
&& chmod -R 777 /etc/nginx/*
References:
http://mailman.nginx.org/pipermail/nginx-devel/2015-November/007511.html
https://github.com/fsimorbrian/openshift-secure-routes
Why does this openshift route succeed in CDK but fail in RHEL7 Atomic?
Best practice is that you do not run your containers as root. Many Docker images out there, even some official images, ignore this and require you to run as root. Advice is generally that you should set up the image so that your application doesn't require root and can start up as a non root user you set up in the Dockerfile. Even this advice though isn't the most secure option for a couple of reasons.
The first is that they will say to use USER username, where username is obviously not root. For a platform that is hosting that image, that doesn't actually guarantee your application isn't running as root. This is because a named user such as username could be mapped to uid of 0 in the container and so still running with root privileges. To allow a platform to properly verify that your image isn't set up to run as root, you should use a uid instead of username. That should be anything except uid of 0.
The second problem is that although running as a specific non root user in your own Docker service instance may be fine, it isn't when you consider a multi tenant environment, be that for different users, or even different applications where it is important that the different applications can't access each other in any way.
In a multi tenant environment, the safest thing you can do is to run all applications owned by a specific account, or in different projects, as different users. One reason this is import is from the perspective of data access on persistent volumes. If everything was running as the same user and it managed to get access to persistent volumes it shouldn't, it could see data from other applications.
As far as OpenShift goes, by default it runs with the highest level of security to protect you. Thus, applications in one project are run with a different user to applications in another project.
You can reduce the security measures and override this if you have the appropriate privileges, but you should only make changes if you are comfortable that the application you are doing it for has a low risk profile. That is, you don't grab some arbitrary Docker image off the Internet you don't know anything about and let it run as root.
To learn more about changing the security context constraints around a specific application start by reading through:
https://docs.openshift.com/enterprise/latest/admin_guide/manage_scc.html
You can override the default and say that an image can run as the user it declares in the Dockerfile or even run it as root if need be.
The better way if want the best security is to construct the Docker image so that it can run as any user and not just a specific user.
The general guidelines for how to do this are:
Create a new user account in the container to run the application as. Make the primary group of this account be group ID 0. That is, its group will be that of root, but the user will not. It needs to be group ID 0 as that is what UNIX will default the group to if running as a user that has no entry in the UNIX passwd file.
Any directories/files that the application needs read access to should be readable/accessible by others, or readable/accessible by group root.
Any directories/files that the application needs write access to should be writable by group root.
The application should not require the ability to bind privileged ports. Technically you could workaround that by using Linux capabilities, but some build systems for Docker images, such as Docker Hub automated builds, appear not to support you using aspects of Linux capabilities and so you wouldn't be able to build images using those if needing to use setcap.
Finally, you will find that if using OpenShift Local (CDK) from Red Hat, or the all-in-one VM for OpenShift Origin, that none of this is required. This is because those VM images have purposely been set up to allow as the default policy the ability to run any image, even images wanting to run as root. This is purely so that it is easier to try out arbitrary images you download, but in a production system you really want to be running images in a more secure way, with the ability to run images as root off by default.
If you want to read more about some of the issues around running containers as root and the issues that can come up when a platform runs containers as an arbitrary user ID, have a look at the series of blog posts at:
http://blog.dscpl.com.au/2016/01/roundup-of-docker-issues-when-hosting.html

How to create and run multiple ec2 instances with same configurations and software installed?

Fairly new to cloud computing, so bear with me if question is obvious or silly. With tons of information available on internet, I was able to successfully create an ec2 linux instance and installed R and Rstudio on it. Ran my scripts on it which went really well but took too long (16 hrs) and very expensive as well since I require instances with high memory and vCPUs .
In my programs, I am essentially running the same scripts for different datasets.
My question is, is there any way I can run multiple similar instances of ec2 (with exactly same software installed and my scripts). So, this way, I will be able to run my scripts on every dataset on a separate instance simultaneously in less amount of time.
So what I have tried so far. I have created an AMI image of my existing instance and launched it. But I couldn't SSH it because of its weird username and ip address, something like "root#10.0.0.1". I can see both instances are running (original and the AMI image instance), I can SSH into original but not into the other one. I am able to login to the RStudio for original instance on port 8787.
Another question is how to launch this AMI imaged instance using SSH (Putty) in parallel with original instance. What problem will it cause if I use both of them in the browser (RStudio in this case) simultaneously?
Please help me with this!Thanks!
Problem: For a school project, I was running several machine learning algorithms on pretty large size data which happened to requre 30-35GB of memory and my PC couldn't handle it. I was using R/RStudio. So, I resorted to AWS for my memory limitation problem.
What I did initially: I created an ec2-instance, installed R/RStudio. Everything worked out perfectly and I was able to run my programs on RStudio through browser. I actually, ran my scripts on a very small dataset on this AWS instance to see how things are going. To much of my surprise it took very long for the whole script to run even with this small dataset. Soon enough, I realized that all these algorithms in my programs could be run independently for the same set of features with a little tweak in the scripts.
So, I decided to play with AWS little bit. I recreated the programs such that everything stayed the same except the learning algorithms in each script. In other words, I wanted to simultaneously run a copy of these programs with different algorithms so that I could get everything running simultaneously and produce the results in a smaller amount of time.
Now, my goal was to run multiple copies of this instance (original instance). And I should be able to run RStudio on my browser for each of these instances e.g. 5 ec2 instances will have 5 RStudio running concurrently on browser's different tabs. With that, I would be able to run all RStudio for each instance on my browser.
Then, I created an image (AMI) of this instance and then I created multiple instances from the AMI but I was missing out few points while creating those new instances from AMI which caused the problem I asked in the question above.
I initially suspected that it has something to do with port 8787 and I might not be able to run multiple RStudio for each ec2 instance in the browser. However, that was not the problem at all.
There are few very important things to take care of while you create the new instances from an AMI.
Mistake: While CREATING new instances from this AMI, I was NOT selecting two important things correctly i.e. VPC and Security Group.
Correct method is:
VPC -- On the "Configuration Instance Details" page:
a. Click the "Network" dropdown and select the VPC which was created for the original instance. (Original instance is the one which is used to create the AMI (image))
b. Click the "Auto-assign Public IP" dropdown and select Enable
Security Group -- On the "Configure Security Group" page:
a. for "Assign a security group" option, tick the "Select an existing security group" options
b. If there are more than one security groups in the list then select the one which was created for the original instance (OR create a new Security Group and make sure that it has the same kind of inbound and outbound port accesses)
Once I set this up, as Marc B mentioned in the comments, each instance gets its own IP address, and a local subnet address is assigned as well
IP address of instance looks like : ec2-33-444-22-111.us-west-1.compute.amazonaws.com
subnet looks like: 127.0.0.35
Now, after learning this, I recreated 5 instances from my AMI. So, now I had 5 instances with RStudio on each of them. All of them were running perfectly fine because I was able to SSH into each of them.
Now I thought I should be able to work with these instances in different tabs of the browser and run my scripts in them. But I wasn't able to login to all the RStudio instances in my browser tabs. Only one of them was working fine and the others were just not working in the browser. However, I was able to SSH into all of them from PuTTY. I could have ran my scripts from Linux (SSH) as well but I wanted to run them using RStudio.
After spending a good number of hours on this, I figured out the problem that the RStudio server needs to be started manually for each ec2 instance in the linux except the very first instance.
For one of the ec2-instance (besides the one which was working fine on browser), I did the following to start the RStudio server manually as below:
SSH using PuTTY
Become root: sudo su
Go to this path where RStudio was installed on my Linux instance: cd /usr/lib/rstudio-server/bin
start RServer with this command : rstudio-server start
Now go back to the browser, open another tab and use your ec2-instance address and port number (http://ec2-33-444-22-111.us-west-1.compute.amazonaws.com:8787). And now you should get the login page of RStudio for this instance as well.
Now, with a similar process, I had to manually run RStudio-servers for all other instance in order to be able to access them through the browser. Then I thought, if there is a way to start the RStudio server when Linux starts up every time. Then came up with a solution. To do this, I made a change in one of the configuration files of Linux as follows:
Become root: sudo su
go to this path: cd /etc/rc.d
vi the file rc.local and add the following command:
/usr/lib/rstudio-server/bin/rstudio-server start
save the changes you made.
close the SSH connection
Then, I went back to the AWS console, stopped this instance and created an AMI (image) of it. Now the above changes will be effective for each instance that I create from this AMI i.e. now RStudio server will be started as soon as the instance boots and will be accessible through the browser.
Now I can use multiple RStudio instances using different tabs of my browser. Make sure you are using the correct instance address in the browser. Port number stays same for all i.e. 8787

How do you manage permissions when developing in a Docker container?

When developing in a Docker container on Linux, there is a problem with permissions: how to manage file ownership and permissions between the host and the container.
Imagine that I have a Docker image that runs Ubuntu and an Apache server. Using the default settings for (recent versions of) Apache, the document root will be /var/www/html and Apache will be run as the www-data user.
In order to do some development, I expose the document root via Docker with -v /path/to/my/files:/var/www/html. And this is where the problem arises:
The files in /path/to/my/files are owned by the containers www-data user. If I'm lucky and my host has a www-data user, it will be that user; otherwise, it will be a distinct user local to the container. The permissions on those files will (probably) be 0755.
So, when I'm working away as myself (a user called jsmith), those files cannot be edited by me because of incorrect file permissions & ownership.
I could change the ownership of the files to jsmith, but that will cause problems with Apache - it will have difficulty accessing files in the document root.
I could change the permissions to 0777, but any new files I create in the course of my work will be owned by jsmith.
The end result is that it is necessary to constantly adjust ownership & permissions on the development files. Other people must have this problem, but every post I've seen on the topic of using Docker in a development workflow just kind of overlooks this problem.
I do have a solution, but I'm not entirely happy with it:
I set up a folder at /src/myproject. This holds my development files and is owned by www-data:www-data.
Using BindFS, I mount /src/myproject at ~/myproject, mapping www-data:www-data to jsmith:jsmith. This allows me to edit files in ~/myproject without messing around with permissions.
The Apache Docker container mounts the /src/myproject directory with -v /src/myproject:/var/www/html. Apache sees the www-data ownership of the files and has no problems.
This works well, but seems overly complicated. How do other people solve this problem?
I realize I'm very likely too late but this might be of help to someone.
In your Dockerfile, you could do this:
RUN usermod -u 1000 www-data
RUN groupmod -g 1000 www-data
This may work in some setups.
I can think of two solutions:
Use a common group id among all developers and images. The uid may end up being numeric in the container, but the gid would give at least read access, and optionally write access, without giving it out globally. Use the setgid bit on the containing directories to have files automatically created with this gid. This isn't the cleanest approach, and may lead to giving out access to other group members, but it may be much easier to manage depending on your organization's workflow.
The second option is named volumes, which I believe were added after you asked this question. They let you have the data exist with the uid/gid's known to the containers. This has the downside of moving the data into the internal docker directories where it's less easy to manage outside of a container. However, there are microservices approaches that keep the volume synchronized with an outside source (git pull, rsync, etc) using a dedicated container that mounts the same volume. You essentially move all of the reads and writes of the data into containers, including any backups, update routines, and testing scripts.
Update: A third option I often use for development environments is a run an entrypoint script as root that compares the mounted volume uid/gid to the uid/gid of a user inside the container. If they do not match, the uid/gid of the user inside the container is updated to match the host. This allows developers to reuse the same image across multiple hosts where the uid/gid of each developer may be different on their location machine. The code to do this is included in my bin/fix-perms script that is part of my example base image. The last step of my entrypoint script is to then use gosu to drop from root back to the user, now with the changed uid/gid, and all files written will now match those of the user on the host.
If you happen to be running on MacOS, a recent feature called osxfs automatically corrects for uid/gid mismatches with host volumes.

Resources