For the AWS CDK, how can I determine the appropriate IAM policy and permissions to replace a root account? - aws-sdk

I am setting up aws CDK for a new stack on aws, and the docs say essentially "use the root account to start up, but then set up a policy for a new account":
However, using their recommended assume/* policy almost immediately leads to errors when trying to cdk deploy. So what is a mechanism for determining a policy useful and applicable to setting up a full cloudformation stack deployment?
For one example use case, when setting up continuous integration to deploy multiple stacks how can we avoid giving it the keys to the kingdom?

Since I am part of the aws community builders community, I asked there as well. Suffice it to say that this is a known problem, and not a trivial one to solve. I will try to distill what I learned into an answer here in broad strokes:
Set up permission boundaries. These can forbid an agent from creating new users and privilege escalation. https://aws.amazon.com/blogs/devops/secure-cdk-deployments-with-iam-permission-boundaries/
Walk your shots/walk your permissions. In other terms, give scant few permissions, then try to deploy, find where additional permissions are needed and add those, try to deploy again, rinse and repeat. This is most applicable if you expect the services of a stack to rarely change.
Draft a permission policy of Allow all... ...then deny in particular. In other words, set a policy on the deploying agent that allows * access to all services... ...and then deny permission to create users, change other users, etc etc. Contained within this approach is: bootstrap, then customize https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html#bootstrapping-customizing
Consider a multi-account strategy, where you would add a new aws account for a different project. Because AWS is usage based payment, they allow for multi-accounting in this way where other services might have policies against multiple accounts. Control tower can help with this.

Related

Network Security Group Rule Audit (Azure)

I wondered if anyone has found a way to audit network security groups in Azure, other than trawl through them all in the Azure UI. I have managed to extract info as json, but still its not terribly easy to decipher as its nested quite deeply. Im looking for NSG's with default any/any rules and other poorly applied rules.
We have several hundred Network Security Groups (to give context).
Anyone have any views how best to go about this?
Depending on what you would like to audit in your NSG security rules, the Azure Resource Graph may be more friendly than exporting the the JSON and parsing. It can be called via the REST API, for example from a Logic App, for regular audits.
A simple query for NSGs with security rules allowing traffic to port 22 is below:
az graph query -q "where type == 'microsoft.network/networksecuritygroups' | extend rules = properties.securityRules | mv-expand rules | where rules.properties.destinationPortRanges contains '22' | summarize count() by id"
Another approach to consider would be to use Azure Policy to audit security rules for specific exceptions.
Lastly, if you are more interested in monitoring changes made to your NSGs than specific exceptions, the Resource Change History feature may be what you are looking for. You can target specific resources and review changes over a time window. Doing so would require some automation on your part, calling the Rest API, etc. See: https://learn.microsoft.com/en-us/azure/governance/resource-graph/how-to/get-resource-changes

Automatically Host Content When Specific Nameservers

Basically, this is going to probably an incredibly generic and poorly crafted question. I do apologise in advance for that and hope you can look past that and potentially offer some solutions/help.
I am looking at starting a new project, which I guess functions similar to Shopify in a way. Users will pay a monthly fee and then get their own website which has a store-style thing on it.
I am comfortable with most aspects of making this, however, the one thing I'm not completely sure how to do is if they want to have a custom domain (which I assume most customers would). Based on my experience with services such as Spotify and Tictail, to do this I am going to have to get them to change their nameservers to my nameservers. After that, I'm not completely sure how it will function and how to set it up. All of the files for the sites are going to be pretty much the exact same so I don't need much to change there.
So basically my main question is, how would I develop it to automatically host certain content when someone sets their nameservers as my nameservers? I would like it to be completely automatic if possible, but I don't mind if there is a little manual input.
I'm super sorry if the question isn't worded properly or if it's confusing as I've never developed something like this. A simple point in the right direction would be much appreciated as I'm not too sure where to start with this.
Thanks
It depends on the server technology you use to provide such user related nameservers. If I understand you properly, you are looking to get something like:
# Your service runs here:
http://yourdomain.com
# For the user account (user specific application)
http://{unique_username}.yourdomain.com/
# Then you would have (for N users)
http://username0.yourdomain.com/
http://username1.yourdomain.com/
...
http://usernameN.yourdomain.com/
The way you have to avoid dns hijacking is to actually specify the nameserver in the server host configuration. There are many servers around which provide virtual host configurations to allow many different domain names in the same ip address.
As an example, in nginx this can be done using virtual hosts. In your case you would need to programatically create them. In order to do so, a file must be added to the folder /etc/nginx/sites-available. This could be a file called: /etc/nginx/sites-available/username0 with this content:
server {
listen 80
server_name username0.yourdomain.com;
root /path/to/app/;
...
}
So for your solution, you would create a file per customer user. In order to activate a new created virtualhost (server block), link it in the folder with path: /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-avaible/username1 /etc/nginx/sites-enabled/username1
sudo service nginx reload
Read more about dns hijacking here and have a look to virtual hosts implementations, like the nginx server blocks shown above, or the apache virtual hosts.
Good luck!

What should I use if xip.io is not an option in local install of Openshift?

The Openshift 'all-in-one' Vagrant box uses xip.io. The security team at my company has relayed to us that using 'xip.io' for a wildcard DNS could cause some security concerns. So given that 'xip.io' is not an option, how can I get this set up?
We ran into a similar issue at my company. The best answer, which is a bit dire, is that you'll need to set up your own custom DNS. Sorry to say because it is a bit annoying to do but not all that bad. Use this link, it should give you some guidance.
Basically, you'll need to /etc/dnsmasq.conf file to look like:
# Reverse DNS record for master
host-record=master.example.com,192.168.1.100
# Wildcard DNS for OpenShift Applications - Points to Router
address=/apps.example.com/192.168.1.100
The article goes into great detail. I'm not sure how network savvy you are, but if you're not, then I'd suggest roping in one of your ops guys to assist with this. Without a relatively good understanding of networking, setting this up would be quite difficult.
I understand that you can do this without requiring your own DNS.
Quickest way is to manually add required entries to /etc/hosts of your host system, mapping them to IP address that xip.io address would map to.
Alternatively set up dnsmasq something like the following.
$ cat /usr/local/etc/dnsmasq.conf
address=/.10.2.2.2.xip.io/10.2.2.2
address=/.ain1/10.2.2.2
address=/.10.1.2.2.xip.io/10.1.2.2
address=/.cdk/10.1.2.2
$ls /etc/resolver/
ain1 ain1-xip cdk cdk-xip ddns
$cat /etc/resolver/cdk-xip
domain 10.1.2.2.xip.io
nameserver 127.0.0.1
This is cut and paste from elsewhere and I don't use CDK myself so not sure about the IP addresses here, but I understand this shouldn't require you to set up separate DNS. The 'ain1' entry is for the OpenShift Origin all in one VM, which is equivalent to CDK for OpenShift, but using latest Origin upstream version.

maximising static IPs in google-compute-hosted microservices

My first time I have asked a question on here.
I have an expanding set of services hosted on google compute platform.
The initial round was set up in a very stressed situation, and I am now refactoring.
I currently have 3 EDIT: no thats 4 microservice VM hosts, which will all be HTTPS soon (and so need their own IP). In addition a list of test boxes, as we are developing bits. Test boxes do not need https.
question 1) Does any one have a work-round to get multiple static IPs per host? This is why i have large numbers of hosts.
question 2) How can I have more than a /29 of static IPs (eg 8 or more). This is corporate work, we will pay for services.
question 3) According to google api, I may deallocate static IPs. I cannot find an implementation for this. Do you know of one? As I have built systems like this in the past; I know there is no technical reason why there should not be an API for this.
Bonus Q, Question 4) Is there a mechanism to serialise a saved harddisk out of google cloud? This would make my CEO happy.
An ideal response is a relevent "Fine Manual" to read.
I work on GMT time. All linux hosts, probably not relevant. Although a developer, I can admin most things Linux.
UPDATE: if you delete an IP via gcloud compute addresses delete $name --region europe-west1 but don't delete the IF inside the box, this makes it not static. Which is the objective of Q3.
You can find the answers to your question below:
Its directly not possible to assign multiple IPs to an instance. One workaround to achieve this is to create multiple forwarding rules pointing to the same target pool with that instance.
Its currently not possible to reserve the whole block of IP addresses as the address are randomly assigned to the instances from the pool of IPs available.
If you have reserved static IPs in your project you can can release that IP from one instance and assign it to another.
There is no direct way to that, however one workaround I can think of is to use dd tool to clone your disk as .raw and save that to cloud storage. This clone case be used to create other disks outside your project.
I hope that helps.

How do sites like codepad.org and ideone.com sandbox your program?

I need to compile and run user-submitted scripts on my site, similar to what codepad and ideone do. How can I sandbox these programs so that malicious users don't take down my server?
Specifically, I want to lock them inside an empty directory and prevent them from reading or writing anywhere outside of that, from consuming too much memory or CPU, or from doing anything else malicious.
I will need to communicate with these programs via pipes (over stdin/stdout) from outside the sandbox.
codepad.org has something based on geordi, which runs everything in a chroot (i.e restricted to a subtree of the filesystem) with resource restrictions, and uses the ptrace API to restrict the untrusted program's use of system calls. See http://codepad.org/about .
I've previously used Systrace, another utility for restricting system calls.
If the policy is set up properly, the untrusted program would be prevented from breaking anything in the sandbox or accessing anything it shouldn't, so there might be no need put programs in separate chroots and create and delete them for each run. Although that would provide another layer of protection, which probably wouldn't hurt.
Some time ago I was searching for a sandbox solution to use in an automated assignment evaluation system for CS students. Much like everything else, there is a trade-off between the various properties:
Isolation and access control granularity
Performance and ease of installation/configuration
I eventually decided on a multi-tiered architecture, based on Linux:
Level 0 - Virtualization:
By using one or more virtual machine snapshots for all assignments within a specific time range, it was possible to gain several advantages:
Clear separation of sensitive from non-sensitive data.
At the end of the period (e.g. once per day or after each session) the VM is shutdown and restarted from the snapshot, thus removing any remnants of malicious or rogue code.
A first level of computer resource isolation: each VM has limited disk, CPU and memory resources and the host machine is not directly accessible.
Straight-forward network filtering: By having the VM on an internal interface, the firewall on the host can selectively filter the network connections.
For example, a VM intended for testing students of an introductory programming course could have all incoming and outgoing connections blocked, since students at that level would not have network programming assignments. At higher levels the corresponding VMs could e.g. have all outgoing connections blocked and allow incoming connection only from within the faculty.
It would also make sense to have a separate VM for the Web-based submission system - one that could upload files to the evaluation VMs, but do little else.
Level 1 - Basic cperating-system contraints:
On a Unix OS that would contain the traditional access and resource control mechanisms:
Each sandboxed program could be executed as a separate user, perhaps in a separate chroot jail.
Strict user permissions, possibly with ACLs.
ulimit resource limits on processor time and memory usage.
Execution under nice to reduce priority over more critical processes. On Linux you could also use ionice and cpulimit - I am not sure what equivalents exist on other systems.
Disk quotas.
Per-user connection filtering.
You would probably want to run the compiler as a slightly more privileged user; more memory and CPU time, access to compiler tools and header files e.t.c.
Level 2 - Advanced operating-system constraints:
On Linux I consider that to be the use of a Linux Security Module, such as AppArmor or SELinux to limit access to specific files and/or system calls. Some Linux distributions offer some sandboxing security profiles, but it can still be a long and painful process to get something like this working correctly.
Level 3 - User-space sandboxing solutions:
I have successfully used Systrace in a small scale, as mentioned in this older answer of mine. There several other sandboxing solutions for Linux, such as libsandbox. Such solutions may provide more fine-grained control over the system calls that may be used than LSM-based alternatives, but can have a measurable impact on performance.
Level 4 - Preemptive strikes:
Since you will be compiling the code yourself, rather than executing existing binaries, you have a few additional tools in your hands:
Restrictions based on code metrics; e.g. a simple "Hello World" program should never be larger than 20-30 lines of code.
Selective access to system libraries and header files; if you don't want your users to call connect() you might just restrict access to socket.h.
Static code analysis; disallow assembly code, "weird" string literals (i.e. shell-code) and the use of restricted system functions.
A competent programmer might be able to get around such measures, but as the cost-to-benefit ratio increases they would be far less likely to persist.
Level 0-5 - Monitoring and logging:
You should be monitoring the performance of your system and logging all failed attempts. Not only would you be more likely to interrupt an in-progress attack at a system level, but you might be able to make use of administrative means to protect your system, such as:
calling whatever security officials are in charge of such issues.
finding that persistent little hacker of yours and offering them a job.
The degree of protection that you need and the resources that you are willing to expend to set it up are up to you.
I am the developer of libsandbox mentioned by #thkala, and I do recommend it for use in your project.
Some additional comments on #thkala's answer,
it is fair to classify libsandbox as a user-land tool, but libsandbox does integrate standard OS-level security mechanisms (i.e. chroot, setuid, and resource quota);
restricting access to C/C++ headers, or static analysis of users' code, does NOT prevent system functions like connect() from being called. This is because user code can (1) declare function prototypes by themselves without including system headers, or (2) invoke the underlying, kernel-land system calls without touching wrapper functions in libc;
compile-time protection also deserves attention because malicious C/C++ code can exhaust your CPU with infinite template recursion or pre-processing macro expansion;