Dear viewer, these subtitles were generated by a machine via the service Trint and therefore are (very) buggy. If you are capable, please help us to create good quality subtitles: https://c3subtitles.de/talk/542 Thanks!
Now we have Ed Scouten,
who's working on Cloud Abai,
a way to make this a lot more easier
by building a sandboxing
friendly POSIX runtime environment.
Please give him a warm round of applause.
Thank you. Thank you.
How it works. Yeah, good.
So it's actually nice to see, like, such
a full room over here.
There's only like 10 or 20 spare
seats left.
The last time I gave this talk in Germany
was back at Foxconn, which was in
September, I think, conference
that's in a place close to bomb.
And what was a bit of a
shame was that they planned my talk right
at the end of the first day, right
at around the time that they started
firing up the barbecue, which
which meant that, like, I only had 10 or
20 people attending my talk.
So it's really the opposite experience of
what I'm having over here.
So I'm awake.
My laptop turned itself off.
Now it works again.
Yeah. So before I
start to talk, let me first sort of
introduce myself quickly.
My name's Scouter.
I'm an open source hacker from
the Netherlands back
in 2002.
2000. Yeah, 2002.
When I started studying, I became really
interested in how open source operating
systems worked.
Before that, I was still a Windows user.
But then I started using Linux and,
um, a year or two years later,
I also started using FreeBSD.
I used OpenBSD for some time.
Most of these sort of commonly
used open source operating systems.
I've even tried running them
once.
Some of them I liked a lot, some of them
I didn't really like.
But the ones that sort of stuck with
is freebees the as you can see, my
T-shirt and
I also use Linux on the day to day basis
as well.
So back
late last year, I
actually lived in Germany and
I had my day job where
I did a lot of software making over
there. But there was something that
really sort of caused an itch
that wasn't that I couldn't scratch,
that I couldn't sort of fulfill at my
previous employer, which is the reason
why I left and decided to start my own
small, small scale IT
consulting company called Nuzzi, which is
just Unix with byte ordering issues.
So enough about me.
Let's talk about cloud API, which is what
I've been developing for the last year.
And before I'm going to explain what
Cloud API is, I'm first going to explain
what I think is wrong with Unix.
And lots of people have different
opinions about what's wrong with Unix.
So, you know, this is probably just
bike sharing, trolling.
You know, we'll see at the end of the
talk during the Q&A whether you people
agree or not.
So even though UNIX
is an awesome operating system that I've
used for more than a decade now, there
are like two issues that I've
never really been solved, in my opinion.
So to first of all, is that the system
itself doesn't really stimulate you to
run software in a secure fashion.
And what I mean with that, I'll explain
in a minute.
And it also doesn't really stimulations
right. Reusable, testable software, which
I'll explain afterwards, so.
Let's look at like a very simple use
case, say you have like a Linux server
running somewhere and you want to run a
Web server on, it could be a patsy.
It could be engine X.
It doesn't really matter.
Just some Web server.
This Web server only needs to do like
a handful number of things, just a really
tiny number of things if you really think
about it. So it needs to accept
incoming TCP connections on
which it will receive Hacia to be get
requests and, you know, somehow process
them. Maybe it needs to access some files
on disk stored in some kind of directory.
Maybe if there's like some kind of,
you know, for example, a python or a
B script in there that connects with some
kind of database backend, it also needs
to open a connection to that and then
perform some transactions, computer
responds and send that back across the
DCP connection.
So this is just really if you
sort of look at all of the possible
things that a UNIX program could do, this
is just a really tiny
amount of functionality.
But what you see is once such a program
is compromised, an attacker can basically
just do anything that that user
can do that the Web servers running is,
which is quite a lot of stuff.
So first of all, it could just create
like a table of all the world readable
data under slash.
And, you know, if your file system
permissions are set up in a correct way,
then this might not be not be really
damaging. But, you know,
getting them set up for your entire file
system correctly is in practice pretty
hard. And also, what is really
readable within your company might
actually not be world readable, like
for attackers on the other side of the
Internet.
So there are also some other nasty things
that an attacker can do.
So, for example, it can still invoke
secuity utilities that are provided
quite a large attack surface.
So exploiting those programs can be, of
course, you know, used by an attacker
to gain even more privileges.
And even if that's not the case, an
attacker can still do some really nasty
things. So say an
attacker would manage to break into the
Web server, install some kind of, you
know, back connect
surface where it can, you know, create
login sessions on that system.
Even if you would just update your Web
server to a version that's no longer
vulnerable to a certain exploit, an
attacker could have just register.com job
is that you don't just open it up every
couple of minutes and be back in again.
And even if all of those kinds of things,
you know, accessing the file system is,
you know, really well fenced off,
an attacker can still turn the system
into a botnet node, you know, and take
part in Sindh flooding attacks, sending
spam, that kind of stuff.
So there's a huge disparity between what
a program on UNIX and
should be able to do and what it can do,
because that's just how simple the Unix
security model works.
And you see that over
time people have introduced
sort of frameworks and new features
through the kernel to sort of make
it a lot better.
And in my opinion, you can sort of divide
them in two different categories.
In the first one of them is is
adding more access controls to the system
so that the mindset being
traditional UNIX permissions are sort
of not granular enough, not precise
enough. They can be expressed to
cannot be used to express the actual
restrictions that need to be placed on a
Web server, for example.
So we're going to extend that.
And on Linux, you see
that one of those frameworks is as e
Linux, but another one is F armor and
F armor allows you to create security
policies for every application.
You can create a sort of an additional
separate security policy that's somewhat
stored somewhere in EDC and
that can be used to sort of restrict the
application even further.
But in my opinion, that's not a real
solution to the problem, because what
happens is that, you know,
a software engineer just develops
some kind of Web server, releases it, you
know, froze the code over the fence to
the people at the distributions.
And there the people have to write these
security policies and they actually
don't sort of have to like the full
understanding of how the application
works. And in some cases,
end users might actually need to modify
these policies to get their application
to work correctly.
And I think that this is sort of not how
it should be. It makes security a lot
harder than it actually needs to be.
And the problem is that, for
example, going back to a
Web server example, again, if you would
change, for example, the root directory,
if you observe in your configuration
file, you also need to update it in
your former security policy.
Well, what happens is that some
user tries to do this and for some reason
it doesn't work anymore because he forgot
to update the security policy.
So then he Googles around a bit and then
he just seems like, you know, this is
caused by App Amahoro.
I had the same thing on my Ubuntu system.
So what does the user do?
Objet remove app armor.
Problem solved.
So in
my opinion, these kind of systems are
they simply don't work.
Right.
And then there's a second class of
systems and you know,
over I've called them capability space,
but they're not necessarily capabilities
based. But, you know, just
for the sake of argument, let's just, you
know, frot of Secombe on
Linux and capsicum just in one big
bucket. I'm going.
Explain how capsicum works and a bit more
detail, because I shall see what
we need to this knowledge later on,
what happens with capsicum means that you
just create your Web server like you
Apache for engine starts up
like your regular Unix process.
And the first thing that it does is it
passes the configuration files and the
configuration files that list, for
example, the IP addresses that the system
needs to to listen on
the path names of all the root
directories and it and it
sort of opens up all of those directories
and all of those network connections that
it actually needs.
Then when that part is finished, it calls
a system, a special system called called
the cap enter.
And this sort of Flagg's sort
of an annotation bit in a kernel on the
process to say that this process
is now running in capability's mode.
That's how it's called.
And what happens is that, um,
from that moment on, any sort of
dangerous system call
starts to return. The error code is not
capable and to sort of explain what that
means. So, for example,
that network socket that we opened
because it was sort of the IP address was
mentioned in the configuration file, of
course, it's safe to call except on that
to accept incoming connections.
You know, it's
when you get one of those connections,
it's safe to read and write on them, to
sort of interact with the system on the
other side. That's all safe.
It's also safe to open files underneath
directories that you've opened.
But what's not safe is opening an
arbitrary file on disk saying open
slash slash
password and writing stuff into it.
For example, this is really not allowed,
of course, you know, just opening any
files, not allowed.
And that's how capsicum works.
It turns the system into a system
that uses capability based security.
And that basically means that there is no
global state that a process has.
But the process always sort of has a bag
of capabilities file descriptors
in this case that it can use to access
resources on the system.
And this is already used by quite a lot
of applications on FreeBSD at least.
So you see a list of programs,
DHP, client paying, DCPI
dump. Um, you know, TCAP
is a really good example.
If you think about it. The only thing
that this program has to do is when it
starts up, it has to open the Berkeley
packet filter to capture network traffic.
It needs to make sure that it has a file
descriptor open to your terminal to
actually write messages to it, you know,
which packets were received.
And when it has done that, it can safely
call cap enter.
And if an attacker somehow
manages to trigger a buffer overflow
inside of TGP dump, there is
little to no risk at all.
And this is actually far more likely than
you think, because TCAP is full of all
sorts of packet parsers, it can pass
dozens, maybe hundreds of different
network protocols and all sort of
handwritten parcels to just
find all of the specific interesting
fields inside of all the packet headers.
And there's a fair chance that it might
be some buffer overflow intercept
them. So what you can do is an attacker,
as you can just sort of send all this
random traffic across the network and
just wait for a systems administrator to
run TCP dump.
And when that happens, you can actually
just, you know, trigger a buffer overflow
in a process that's running as the route
user on the system because everyone runs
Tsipi dumpers route.
So
this is a real good model for hardening
all those those Unix utilities, in my
opinion. Um, I really like it.
So my
experience is using capsicum.
Late last year I started playing around
with it and it really works as
advertised.
You know, the implementation of that is
quite robust. And, you know,
the design behind it is all right.
But there is something
that I noticed that really makes it hard
to sort of use this at a larger scale,
something that's larger than just being
ought to be done, because those
utilities, they are fairly small if
you sort of look at your average UNIX
system. So.
My observation is the following code
doesn't really like it if you suddenly
start to disable functionality, that it
depends on code.
So so the best example that I could come
up with, I'll first give you the best
example that I ran into.
There is this crypto libris to crypto
libraries. Even I won't share the name,
but what happens is that they try to open
a referendum.
And what do you do if that fails?
Do you give an error message or do you
terminate?
No, not really. You actually just run,
get time of day and then get the
user I.D. or something like that.
And then just use that as your initial
state for the random number generator
because, you know, the time is random
enough.
So
that's actually pretty bad. So if you're
not using capsicum, this code is
completely safe because opening random
always works.
But as soon as you go cap enter, then it
no longer works and you go through a
different code baff that was sort of
never exposed before on the regular
Unix system and you end up with just
completely unsafe setup.
Now there's also some other
annoying things that I ran into.
So for example, time zones,
if your program starts up and you call
QEP, enter and then run, get time, sorry,
local time, it uses UTC
as your time zone.
The reason for it is it can no longer
exist EDC local time.
But if you call local time at least
once before calling QEP enter, it does
use the local time zone.
The same holds for localization.
Once you call QEP enter, you can no
longer do any conversions of
pieces of text in different character
sets.
You know, it's just a real
mess. So my observation is,
if you just
take like a really big Unix application,
like affect your Engine X and you
put a cap intercall somewhere, you know,
somewhere a main, then the program will
just explode in sort of
ways that are really hard to cure.
It's basically just, you know, you
hacking on it for months just to get it
working. There's no proper guided way of
porting a larger application over.
So what you see in practice is that
smaller Unix applications and Fevzi,
for example, are being ported over and
sort of in-house maintained code, like,
for example, the code that runs in your
chrome tabs is being run in Secombe.
But it's not as if most
Unix applications make use of this.
If you just run on your system, there's
maybe only one or two processes on there.
It actually uses Capsicum
or Secombe BBF, so.
That's really what I sort of dislike
about capsicum and Secombe,
they work for these really sort of
you artificial or, well,
self developed use cases, but not for
sort of the the long tail
of software.
So a second problem that I
have with unit security is that UNIX
makes it really hard to just run
untrusted programs directly on top of
them. So if you just download a random
ILF executable from the Internet and run,
slash, run on it, or
if it's cold, then you really mess up
your system. Don't do this.
I really wouldn't do this.
Running it in jails, free BC jail,
running it in Docker is a bit safer
and the darker people are really
convinced that docker's safe enough to
run arbitrary executables.
But I guess most
security experts really wouldn't dare
this etre running it inside of
a VM. Is it safe
while also not always.
I guess there's likely to talk another
talk at this conference that sort of
debunks the the
safety of systems like Sandack VM.
But it's safe enough for most people.
And this really makes me wonder, why
can't you just safely run third party
executables directly?
Why do I first need to set up a VM?
You spend an hour installing VMware,
etc., or virtual box,
putting a distro in there and just
to run the single executable, why isn't
there like a sane, simple environment
that I can use to run the sandbox
executables?
So as I mentioned before, that the second
problem I have with you is regarding
reusability and testability and.
When I first wrote these slides, I had a
really hard time coming up with the right
way to sort of explain what
I think is wrong with reusability and
testability. So eventually I came
up with a way of sort of
coming up with an analogy, and instead
of looking at Eunuch's, let's sort
of take a step back and take a look at
sort of software development in general,
namely, you know, programing.
And let's just take a look at Java
programing. For example, if you would
write your simple Web server in Java, you
would probably write something like this.
You'd start out with a class class Web
server and it has a constructor.
And this constructor sets a couple of
internal members at initializes the
class. And what does it do?
It creates a TCP socket that runs on Port
80 and it has some
kind of root directory by your files are
stored.
This works, but most people would agree
with me that this is not the sort of the
tidiest code you would write if you would
just write this for your employer and
send it out for code review.
And hopefully one of your colleagues will
just, you know, come over to your desk
and slap you in the face
because because,
you know, this Web server is completely
not flexible. Reuseable, of course.
I mean, it always this on board and it
always uses the same directory.
So what you do is you sort of
extend the constructor, make
it possible to pass in a couple of extra
parameters, name the airport number and
the root directory.
This is already a step in the right
direction. But then you're sort of
veteran Java programmer.
My colleague comes to you and says,
no, no, this is still wrong.
You know, you need to use interfaces or
come up with nice abstractions
and layers in your application to make it
more easy to test.
So most Java programmers would
actually write something like this,
namely, instead of just creating
like the TCP socket inside of the class,
you just make it possible that a sort of
an abstract socket type can be passed in
and the same thing holds for the falsus
nexus. Instead of putting all of that
filesystem X's logic inside of the
Web server class, you could also just
create an interface that, for example,
has a function, get
full content and you pass in like a file
name or something like that. And it just
returns also file contents
of some kind of buffer.
And what you can do now with this class
is you can
test the entire class without
actually constructing a single
networking socket through the operating
system or accessing a single file on
disk. This is something that you can test
really easily.
Now, if we take a UNIX applications,
you know, I just showed you like three
different ways of solving it.
If you now look at Unix applications, you
see that they always sort of
stick to one of the first two examples
that I showed. It's either the case that
the behavior of the applications is hard
coded or they you
know, they they write stuff to hard code
locations on this score, assume certain,
you know, locations where
they can access services, for example,
UNIX utilities, they all sort of somehow
know that they can open fire run
name, server caching, demon, dot,
whatever to to exist like a name server
caching. There's no actually way to sort
of override this behavior
really easily. So if they don't hard code
that kind of behavior, it's typically
stored in configuration files that are
stored at a hardcoded locations as well.
And what you see is that application are
is required to resources on behalf of you
instead of having them.
PASTAN So
your Web server configuration, you don't
start a Web server and provide it to
network sockets that it needs to use.
Instead, you write in the configuration
files on which IP address important,
which you listen. And this is really bad,
in my opinion, because it doesn't allow
you to sort of customize
the behavior of the application.
Say you want to use a TCP socket that has
custom TCAP Tynemouth parameters
or retransmission logic.
If you want to add support for this, you
actually need to add it to the Web
server, because when it passes the
configuration file, there needs to be an
extra configuration attribute in there
that allows you to specify
the parameters or any options and
those that need to be the use
to create the TCP socket.
So the Web server just builds
up this huge baggage of all these
configuration options that could have
been sort
of placed outside of the Web server.
There's no reason why they needed to be
in there. So Unix
doesn't use dependency injection.
And I think that this is a double
standard. We're really hammering towards
having testable and reusable software,
but apparently we don't care about this
at the application level.
So here's an example of a reusable,
untestable web server.
I won't spend too much time on this, but
what happens is instead of just creating
the DSP sockets yourself, you could just
assume that standard in it is
a TCP socket, for example, and then
you can just start up this Web server in
any way. So, for example, it doesn't
matter whether you use an IP before an
IPv6 socket, it still works.
It can use TGP, cetp, any
kind of stream protocol out there.
It can listen on any other support.
No, the funny thing is you can even
create a socket once and spawn
a whole bunch of Web servers all using
the same follow script.
And then you've implemented concurrency
without any additional effort.
And this web service, of course, testable
because you can just use a unique socket
to inject requests and capture
the responses again.
So this is a, in my opinion, sort of
a better model of what we see in Unix
right now.
So now I've, you know, spent a fair
time introducing or explaining what
I think is wrong with Cloud, with Unix
Cloud API.
Now, I'm going to explain what Cloud API
is. And, you know, as you
might have guessed, it's something that
sort of attempts to solve this.
So Cloud API
is a new Unix like runtime
environment that
is think of it as.
POSIX, the unique standard, plus
all of the stuff that's provided by
capsicum, minus all of the
stuff that conflicts with capsicum.
So this makes it
a lot easier to write software that works
well with capsicum.
So if you would now write opened, if
you read them, instead of just like
making the program start up and fill at
runtime, it now just feels to compile.
And it's of course annoying if
gold doesn't compile, but it's a lot
easier to fix, you know, compilation
bugs than it is to sort of track down
these issues caused by the security
framework. Because what I
explained before, if the crypto library
that I try to open do you random and then
fill back to weak entropy, that's
something that you really don't notice.
The only way you can discover it is if
you sort of trace the application and
sort of take a look at the system called
behavior and see what it does.
That's how I, you know,
discovered this issue.
But if you remove all of those interfaces
and it becomes really obvious where sort
of the the problem points in your
application, it makes it a lot easier to
make software run in such a sandbox
environment.
So what's also nice about such an
environment is that applications can
no longer just create arbitrary TCP
sockets or something like that or open
arbitrary files on disk.
There are no more global name spaces,
as they're called, and
this makes it really hard to hard code
all of that kind of stuff in the
application. So it's sort of you're
really forcing the application to be
written in a testable way, and
I think that's good.
It shouldn't be like this unconditionally
because there's sort of of, of course, a
very large amount of legacy software,
existing UNIX software that needs to
work. But it's not a bad
idea to also, Nekesa, that sort of a
clean slate Unix environment where
testability and security is sort of a
prime focus.
And that's also like the point that I
want to make at the bottom of the slide.
Often when I give this talk at
conferences, there are people that sort
of walk up to the microphone and say,
like, this is nice, but it wouldn't work
for traditional Unix
use case X.
That's of course, really not what I'm
focusing on. This is really a clean slate
approach.
So just to sort of rehash what
a cloud API program can do by default, if
you would just start up the simplest
cloud API process possible, it can
still allocate memory.
It can create pipes, it can create
socket pairs, it can create shared
memory. In other words, it can do ipse
with itself.
It can also spawn Freds and it can also
spawn subprocesses.
So it can Falke
or. Yeah, creating threads
is not necessarily Forkan, but it can
also form and it can also interact with
some clocks. It can also even get random
data from the kernel.
Those are all things that are, you know,
really not harmful in any way.
If you're just sort of a small, tiny
program running on some kind of computer,
there's really no harm in getting the
time of day or getting some random data
from the kernel.
But what the programs cannot do is open,
arbitrary popson disk create network
connections and it can also not just send
signals to other processes on the system.
That's already fenced off, so
the simplest cloud by program, if you
would, just random thoughts with
whatever, it wouldn't be able to do any
harm on your system.
So then you want to sort of grant
additional rights to this program to
actually make it functional, and you do
that in the form of file descriptors, so
you make sure that your program is
started up with the right set of follow
scripts. And that's really critical.
Just to make sure that you
use the right set of follow scriptures to
start up your process.
And what you can do is you can just use
follow descriptors to directories to
access parts of the file system, which
I've already mentioned.
And this is really nice because in
practice, this means that most
of you people are probably familiar with
the change root system, calling Unix,
where you can lock up a process in the
single directory.
This is sort of change route on steroids.
It allows you to create multiple change
routes. Every file descriptor on its own
is its own separate change route that you
can access files underneath.
So it's really powerful
sockets to make a program network
accessible. But it's also really nice to
set unique supports.
Follow scripter passing
if you have a unique socket so it doesn't
work for a TCP socket or anything, but
just a local unique socket, you can
actually be sure to follow script from
one side of the socket and it sort
of pops out on the other side.
And this sort of allows for some really
complex constructs where
a program starts up.
It doesn't have a lot of rights by
default, but it really needs
a sort of a specific right later on.
It can sort of send an RPG over to some
kind of process like, hey,
I need to deliver this email for user X.
Could you please give me a file
descriptor to that person's mailbox and
that other process then sort of sends a
file descriptor back to you and you can
sort of write an email into it.
So this is a really powerful construct
and also something that supports the
so-called process descriptors.
As I mentioned in the previous slide, you
can't just send kill signals to arbitrary
processes.
So what capsicum did and what cloud API
also supports this process descriptors,
namely, there's a special for call.
And if you invoke that call, you actually
get a file descriptor to the
child process.
If you call close and that follows a
script, it automatically kills a child
process. So there's also no way for you
to sort of leave resources behind.
It should be noted, important mentioned
at some previous conference, someone made
the smart remark.
Yes, but what if you can pass process
descriptors through unique sockets?
Because you could, for example, allow
a process of scripter to be passed
through the child process itself and then
the child process can remain alive
indefinitely.
So that's not possible.
Process descriptors are not possible for
unique sockets. That's that's a
restriction that's placed on this model.
File descriptors also have permission,
Titmouse, and they allow you to sort of
really gradually turn off certain
privileges so you could create a piece
of shit memory.
Scheft memory file descriptor, which is
rewritable for you, but then you
duplicate to follow Scripter about on
that second instance, you remove the
right bits and that follows descriptor.
You send it over to another process and
then that other process can only read
from the shared memory space and not
write into it.
So this is also an important concept.
Without this file descriptor permission
titmouse, then the system would be a lot
weaker than it is right now.
So the secure web service, how would you
live in Cloud Abai?
Well, it's pretty straightforward
for every sort of bullet point that I had
and one of the previous slides, you just
replace it by a file descriptor
essentially. So for example,
you can use an affinity.
Or if I had six TCP
socket for all the incoming HTTP
requests, you can use read-only
file descriptor for the directory
containing all of the Webroot files.
So it only has to read capability's but
not write and not truncate, etc..
So that means that an attacker can never
actually modify, modify the files that
are stored on your web server root
directory.
And you can also give this web
server and append only file descriptor
that only has the right capability set to
it, meaning that the only thing
that an attacker can do in the worst case
is append garbage to the log file.
It cannot truncate lock files, can
overwrite its previous entries.
It can only add more stuff to it, which
is nice.
So when I started hacking on this, I
observed that Unix becomes really tiny,
really small if you remove all of this
legacy cruft from it to begin with, but
also all of the interfaces that are
incompatible with the security model.
So Cloud API only has 58 system
calls and
which is pretty tiny, and
especially if you compare to Linux, for
example, because Linux has 300 and
FreeBSD even as almost 400.
I think so it's
a lot simpler to implement.
And what this means is that you can add
support for Cloud API to existing
operating systems.
So I started adding support
for Cloud API to free BSD and it only
required me to write, I think, 6000
lines of code.
And that is sort of enough support to run
all of the sort of to run all of those
cloud API system calls.
And now I'm also working on adding
support to Linux and that be easy to not
be used for this really robust because
it's sort of similar in structure to
FreeBSD.
Linux requires some more work because
sort of being able to run
multiple binary interfaces is something
that's not sort of a core concept
of the Linux kernel doesn't really
support that. So I had to add some moves
to that. But it means that
you only patch up the operating systems
by adding a couple of thousand lines of
code and then you can
run programs to.
Recombining them, which is pretty sweet
in my opinion, especially for sort of
cloud computing cases where
you're just a hosting provider and want
to run binaries that are provided by
other people. This is sort of a real
killer feature, in my opinion.
So now I'm going to explain
a couple more things. For example, how
can you develop software for cloud API?
So, first of all, compiling in general
is pretty hard.
This means that it's typically not that
easy to build software for Cloud API out
of the box.
And of course, I've been working on
making this a lot smoother and I'll
explain how I've been doing that in the
next couple of days.
But the problem is that the
toolchain to the entire toolchain
for building cloud API software depends
on a lot of sort of separate components.
So there's a compiler, assembler Linko,
that you need a standard library, C++
Library Exception Handling Library, MAFF
Library.
It's just a whole list.
And then you only have sort of the bare
minimum of building cloud API software.
And setting that up is pretty time
consuming, of course.
And in addition to that, you also need to
patch up any piece of software that you
want to use. So removal
of all of this capability, unaware APIs
really breaks to build in a couple of
places. And at the same time, I'm also
trying to cut down on sort of some
non-unique extensions that
are either obsolete or don't make
a lot of sense where the C standard has
already caught up and provide interface
that are a lot nicer and also really
annoying. Some build infrastructure like
all the doesn't even support cloud API to
begin with. It does now.
But that means if you have any source
darbo from before March 2015,
if you Randallstown configure on it and
want to cross compile something for cloud
API, it will simply say, I don't know
this operating system.
So that's a bit
annoying. So to to mitigate this, I've
been working on something called the Cloud
API Port's collection and what it is.
It's just a collection of build scripts
that allow you to build
a whole bunch of open source libraries.
And libraries include Boost, which
is really nice of you to C++ programing.
Kerl if you want to do some HTP access,
Jilib, which is part of a lot of them,
sort of garnham desktop centric
applications.
There's even crypto libraries as well.
And also I've started working on some
scripting language support.
Lubar in this case I'm working on Python
in the meantime, which is going to be a
lot more exciting, of course.
But what's nice about API ports is that
it builds those packages once
I build them on my Linux workstation
or my FreeBSD server, and then it turns
them into a bunch of native packages for
different operating systems.
So it automatically generates freebees
the packages, Debian packages, etc..
So what you as an end user only need to
do is you can just go to like my
website if you the link at the very end
of the stock and it has some instructions
on how you can add a couple of lines to
your Etsy app sources of list or
your freebees the package configuration,
and then you can just use objets or pkg
to fetch those packages.
And they're identical across the
operating system. They're like byte for
byte identical.
And this means that you have a really
consistent development environment that
you can use to develop software so it
doesn't matter if you're compiling an
application or Linux or BSD in
theory, unfortunately, not in practice
that the checksums of the binaries should
be identical, which is really nice and
heterogeneous development environment.
Um, I want to explain why
the binaries aren't exactly identical,
but it's if someone wants to grab a beer
with me, I can explain. It is horrible.
So to clarify, these
packages don't contain any native
build tools.
These packages are all built on my
Phoebes, your Linux system, and they
don't have any cross compiler that you
can run on OpenBSD.
These are just across compound libraries.
And the goal is that sort of the
actual native tooling needs to be
provided by your own operating system
vendor yourself.
So if you're a package maintainer for
some kind of distro operating system, you
know, I'd love to talk to you because I
can only always use cloud API packages
for more operating systems.
So here's just like a real
quick explanation of how you install such
a cross compiler toolchain on Freebo is
the icepick FreeBSD
year because the steps are a bit
easier than that on Linux.
And I wanted to make it look pretty, of
course, and
so on freebees that you first just run
this command package, install cloud API
toolchain, which gives you a copy of the
latest version of Klang and the latest
version of Utils targeting
Cloud API. And these packages are
provided by freebees Needham's.
Once you're done, you already have a
compiler, but it can't compile anything
because there's not a single cloud API
library installed in your system.
So what you do is you just add a
couple of snippets to slash EDC and
then you can run package update, followed
by, you know, this long package installed
command. And you know what
you see over here.
This is the name of the architecture X
86 64 Cloud API, and
this is the name of the package and in
the runtime.
So if you install this package, you get a
C library, a standard C++ library,
enough to do standard C++ hacking.
And then once that's done, you can
already just invoke the cross compiler
and compile any software you like, even
including Hello World Applications.
So now that I've explained how you can
sort of develop your Cloud API software,
we're going to look at starting them up.
And it's actually
sort of more interesting than you think.
There's more to it than meets the eye
if we're going to take a look at a very
simple Unix application.
So, for example, many
people have used this application.
I will need to explain what this tool
does it
anyway.
What we do is instead of just
calling, you know, open there
on Dottore, what else does by default,
it opens the current directory and
fetches the directory entries.
There's no way we can do this because the
application has no working directory
anymore. It's simply not there anymore in
cloud API. So we call F.T.
opened here, which allows us to open a
directory by file descriptor.
We then there on it in a loop
and then just print all of the entries
that are in there, you also see that
there is no standard out in this runtime
environment.
You know, it's really just we need to
assume that standard in our sorry
standard out happens to correspond with
a script or one. So that's what the FDA
open call for.
So how can we invoked
this application in a bit of a sort of a
less traditional way?
We first compile it, run it through cross
compiler, then we load up a kernel module
that's needed on FreeBSD to to run this
nice thing as this is already just
integrated into FreeBSD 11 by
default. So if you just download the
latest development snapshot of freebees
the run called Loudcloud Cloud API
64, it works out of the box.
No packages needed, no patches need.
It just works pretty awesome.
And then when you have the binary, you
can just run less.
But we need to provide it a file
descriptor to a directory of
a ophthalmoscope to zero.
We just run such a small one and
see which works.
It prints all of the entries in the
directory. So this is like a cloud
API. Hello. World application in a
certain way.
So even though this works,
this is not really a natural way of
starting processes.
It can really get out of hand.
Starting up a Web server with 20
different file descriptors, two different
DSP connections, etc..
It really doesn't work.
It's the shell is not meant for that.
Even to make it worse, there's not a same
portable way in which you can create
network sockets through the shell, of
course.
And how do you know the ordering of the
follow scripture's? If you have a web
server that uses twentyfold descriptors,
how can you be certain that follow script
of 15 was actually the one that
corresponded with the network?
So maybe that was a log file or
it gets out of hand quickly.
So please don't use Cloud Abi in this
way. It's it's a mess.
And also a problem with this approach is
you really you sorry, lose
the existing paradigm where you can
specify complete applications from a
single configuration file.
Right now you can just go to EDC, made
changes to configuration file and restart
the service and it works.
If you would just started for Michele,
you would have maybe a separate
configuration file with program
attributes, but then you'd also need to
start up the Web server with all the
different file descriptors.
So it sort of turns
it into do so two different ways of
configuring the application, namely your
sort of configuration attributes
and follow script. So if you're thinking
about a way to sort of streamline this
process, to make it a lot easier and
safer and saner to start processes.
So I came up with a launch or two called
Cloud API Run, which is only
a couple of lines of sorry, 100
or 200 lines of C-code biggest, fairly
tiny.
And what it does, it sort of replaces
traditional string command line
arguments. So aragvi
by a tree structure that
semantically looks a lot like Yamal
and.
I'm just going to sort of explain in the
next couple of slides for what it looks
like, and then it sort of becomes more
obvious how it works.
So assume that you sort of have a
traditional Unix process.
So not a cloud API process that has a
YAML configuration file.
You could, for example, have a schematic,
looks a bit like this.
So you specify a hostname that's written
in error messages or log file entries,
a number of concurrent connections if it
has some kind of flat pool inside of it,
an IP IP address and board number, which
it needs to listen, a log file in the
root directory with cloud
API run. What you do is you sort
of annotate this fall in a special way
instead of just specifying these PAF
names directly like it did in this title
like this, IP addresses over there use
a special tag Yamas apparently
type language. I didn't really notice a
notice before I started working on this,
but I've just created a couple of custom
types tags that you can use to annotate
which strings are actually part names
and which strings are actually IP
addresses on which you need to bind.
So what happens is the quality of you I
run parses this YAML file, it
scans over all the entries in there.
It sees all those stock in the file tags
and then just replaces them by the actual
follow script of those directories and
network socket addresses.
So eventually end up with something
that looks like this, just like a
preprocessing pass that gets rid of all
of that stuff. And this is actually
what's being passed on to the
application.
So if you're writing a program instead of
using information, you can now use an
alternative prototype called programing.
And there is a set of functions provided
by an arc data header.
And these allow you to sort of
traverse over this data structure,
extract file descriptors from it, extract
scalar values like integers and strings
and booleans also allows you to sort of
iterate over all the maps and
dictionaries and all of the things that
are stored in that YAML file.
And
this is like a sort of a really nice
compromise, in my opinion, because it
doesn't make it harder to configure
services than the way it is right now.
You still have a single configuration
followed, allows you to sort of both add
configuration attributes, but also
resource dependencies that you want to
list. And it also makes it impossible
to sort of get the ordering of the file
descriptors wrong. Of course.
And what's also really nice of you I run
also ensures that all file descriptors
that happen to be open at the time but
weren't specified inside of this
YAML configuration file are closed.
So there's no longer any accidental
leakage of file descriptors into
processes for software
developers. That means that there's no
longer a need to write configuration file
Pasos. You can just use this data
structure to to sort
of browse through all the configuration
parameters.
And there's also no longer need to sort
of write code to acquire all those
resources and start startup, which is
nice. So once you're in programing, you
can already start working instead of
first having tens
of thousands of lines of parsing
configuration file and acquiring all the
resources to where you need them.
So now quickly go
like in the last remaining minutes that I
have, I'm going to explain some use cases
for cloud API that I've been thinking of.
Maybe the audience can think of some
other cool use cases
and I'd love to hear about that.
So at one of my previous employers,
I, I was working on some kind
of network security appliance and
one of the things we had was a spam
filter that was running on this and this
spam filter. We bought it from some kind
of third party vendor.
I don't even know the name of the company
anymore.
But the problem is that this is just a
unique process that's just running on
your hardware appliance, you know, it's
just a third party binary bulb that
you're running.
And what is this application was
implemented as a cloud API program, and
it wasn't modeled in a really simple way
where emails would be sent in on a pipe,
for example, and the application would
then just return a true or false
response, whether it was a spam email or
not.
That means that if there some kind of
buffer overflow in this spam filter,
email spam filter system,
then there's almost no impact
to it. The attacker can just sort of
consume some more CPU cycles on your
hardware appliance, but that's all it can
eventually do or maybe falsely return
that the email wasn't spam.
But the question is whether that's a
really bad thing. It's still better than
just, you know, eventually maybe
even becoming root on this
hardware appliance.
Same old for network appliances.
There's a lot of research right now
towards doing
pacard filtering and userspace,
for example. NetApp is one of those
projects where you can really efficiently
get network packets into userspace
and implement all of the firewall logic
and userspace and then send a message
back to the kernel whether the package
should be accepted or rejected.
Something like this could also be run as
a cloud API application to just make a
lot more secure.
So high level question management, this
is also a really interesting one, in my
opinion, by applications
have the property that the dependencies
of them are sort of really known up
front.
It's not as if they start up and then
acquire the resources themselves.
You already know what they they they
depend on so far, some kind of custom
management system. This would also be
really nice.
You have a couple of web front end
applications, a database back, some
batch jobs, and all of those have to
dependencies that you can sort of express
in a graph.
And based on that graph, the cluster
management system can start them up in
the right order.
And sure, that they're sort of started up
close to each other.
So not that, for example, the database
back end is started up in a data center
in Japan while the Web front lines are
started up in the data center here in
Germany. You can really improve the
locality if you sort of old if you know
all that information up front.
It also makes migration of processes a
bit easier because you actually know what
the process depends on.
So you know what? You need to migrate to
the honor system as well.
And sort of this is really looking
really far ahead and, you know, the
question is whether it's ever going to
happen, of course. But still, I like to
dream about this.
There's this service called the Amazon,
the EU and Amazon, etc.
is really nice in my opinion,
that you can just run arbitrary
Unix programs in the cloud.
It doesn't really matter which program
language they're written in.
You can just create your own Linux
VM and just run a Web
server service written in Rust or
whatever you like.
Google app engine on the other end is
sort of a more Manwich system where you
just build your own application, either
Python, Jafo or go.
You just throw it over the fence and they
start it up for you and automatically
scale it up.
And already sort of
if a system goes down, they automatically
start it up on a different system.
So it's a lot more menaged.
And I think the Cloud API could be used
to sort of combine the two of these where
you sort of had a more managed system
where you don't actually care about
individual Linux or unique systems
anymore, but it still allows you
to just build programs in any programing
language you like. So
maybe we'll see something like this in
the future appear would be pretty
awesome.
So this is all I have to say for now
because we're sort of way out of time.
I guess here are a couple of things that
are interesting. So first of all, there's
a link to my sort of consulting company's
website. But on that site, you can also
find documentation of how to use this.
All of this is open source.
So here at the bottom are a couple of
links to my guitar page for
my company. So the top link is to the C
library that you need to use for cloud
API. And the bottom one is the package
collection. So if you browse through the
package collection and you see that some
kind of package is missing that you like.
Well, then, if you're really into that
stuff, then, you know, you can always
let me pull requests and get out.
And there's also an IOC channel clouded
Beliefnet. So if you'd like to look
around, then that's a place you can go
to. And that's all I have to say for now.
Thanks for attending my talk.
Thank you very much.
If you have questions, please line up
behind the four microphones we have here.
Are there questions from Iasi Bono?
No questions from IREs, no questions from
Iasi.
We'll start with the microphone in the
left.
OK, thank you for your talk.
One of the problems you mentioned was
that a lot of primitives
we use, for instance, in
C libraries are
that you are dependent
from a global state of the system
for for instance, it's C local
time, but maybe it's
the result that that comes or everything
like that. So I'm sorry, could you repeat
that question? Yeah.
So how do you solve this problem
of being dependent of a global state
of the system in its CEO,
for instance, c local teams that you
mentioned or.
Yeah, so that's a really good question.
So and so.
So first of all, I, I do
realize that systems will always
have global state in them and trying
to eliminate that is just far too
optimistic.
But what I think is if at the
very sort of bottom, if you look at sort
of the core primitives that are exported
by the operating system, they should not
be bound to any global state
global status, easier to introduce and to
eliminate.
And if you have sort of an
environment where there is global state,
for example, there is a workstation that
has a login session that has a menu
bar at the top or something like that,
it's always easier to introduce it in a
programing userspace than it is to sort
of already let a trickle
through through the core APIs of the
operating system, because that's the
reason why we need virtualization and
sort of really trickled into the APIs.
And now applications really depend on the
global stage.
So I'm not saying we can eliminate it,
but it shouldn't be part of the core
API.
Did it answer your question?
Yeah. So if you develop a
cloud
application, how do you get to the local
time?
You have to personalize
local time in the.
Yeah. So for example, it could be the
case that your configuration
file for your application is like a time
zone, Kolon, Europe's Amsterdam
or Europe's Lightburn, et cetera.
And then inside of your application
you use that time zone instead of being
stuck to a global times and that
specified in such EDC.
The microphone from the right place,
yes, over there.
Hello, can you hear me OK?
Yes, I can hear. So you mentioned
you started with a clean slate.
It was definitely partial clean slate.
Cherryholmes is a Cambridge University
project. They made their own custom risk
architecture with Custom Memory
Management Unit, which can protect region
of memory known as a capability.
And then at they have a custom
operating system and a custom programing
language, which then every time
the instantiate an object, it's coupled
not with just information,
but also authority know
capabilities to perform some action on
a resource.
And this actually gives you a
multiplicative attack
surface area reduction because every
abstraction layer of your program, you're
reducing attack surface area.
Yeah, this is
like kind of like halfway
or partial way there.
It's definitely implement some
capability, object
capability, security, but not
the full thing.
So so it's really awesome that you
brought up a cherry.
So I actually know that
the people working on Cherry pretty well.
I'm very thoroughly
involved with, like, you know, I checked
with at least a couple of them people
once every couple of weeks.
I hear all that news coming in.
And so what the cherry
people are doing is they're building a
CPU that has capability
registers built in.
So instead of having operating system
level capabilities where you have
followed the script resecting
capabilities, you can actually say,
you know, I here have a tiny piece of
memory, a buffer where an application
can right into. But now I'm removing the
the right bit from the piece of memory
and passing that onto some other thread
or code routine inside of the process, if
I understand correctly.
And I mean, it would be really awesome
if like cherry and cloudy I
had children, that would be the most
awesome thing ever.
And it's really cool because I'm
maybe, you know, Bruce Davis, who's a
freebees developer as well, actually.
Actually, I work on TAHO laughs,
which is a cryptographic capability
system, OK?
And it has a different security model
that works over network.
So you're saying the cloud.
Maybe I should have kids with that.
Yeah. Yeah, potentially.
OK, well we should chat
afterwards. I just wanted to like
mention that my different
perspective. Hm.
Yeah. Yeah. I mean yeah
it's really cool that you mentioned that
because I mean just look it up Cherry.
It's also developed by the University of
Cambridge.
Really awesome project.
Cool.
Next question from the front left
microphone followed by the front right
microphone up front
rear left microphone, rear
left microphone first, first a front
left, then the rear
me or OK.
Oh so the question about time more
remark than the question.
So I don't know what your model but
actually providing the ability
to read the time can be a dangerous
because you know,
Glock's
kind of unique and hard of hardware
details and it can be
used to identify the machine.
Yeah. Yeah.
So this is also really good.
Remarque So I have to say that I'm,
you know, famous last words,
even Cloud Abi is not perfect.
So, for example, the fact is you can
access those clocks. And the reason
that I have for this is to following.
So POSIX has already a nice
standardized interface for dealing
with directories as file
descriptors. So open at the system called
that I mentioned in these slides is
actually part of POSIX 2008.
And with that in mind, I could sort
of think that there's a reasonable sort
of way I can expect
people to adopt this.
The problem of Klok APIs is it would be
really awesome if there was also really a
way where you can say, I want to pass on
a fake LOC to this application.
This application is not running in 2015,
but in the future or the past
could even be useful for testing 2058
compliance bugs.
You know, but the problem is there is no
sort of standardized API for this.
So right now,
to sort of make the adoption go a lot
faster and not sort of cause a lot of
bike sharing and trolling, I
decided to just stick to a subset of
Unix. And unfortunately, that doesn't
provide any way to inject custom
random number generators or random clocks
or that kind of stuff.
Yeah, but but it's a really good remark.
Yeah. Thank you.
The left rear microphone, please.
OK, there you are.
How does a capability based security
model play with IPC, especially when
there's no parent child relation between
the processes?
Sorry, could you repeat the question?
OK, how does your capability
based security model play with the entire
process communication, especially when
there's no parent child
relation between the processes?
Well, I mean, so.
Now, I need to bring up like a list of
all the individual
requirements or, you know,
axioms that sort of specify
what a capability based security system
is, but there is
a way of.
If I if my interpretation of Kapiti based
security is correct, eventually what it
boils down to is that every program on
its own has its own bag
of tokens that it holds onto its own
capabilities. And it's in Cloud-based
case file descriptors.
And every process can do a couple
of things with those file descriptors.
Namely, it can discard those file
descriptors at free will.
You can just close your own file
descriptors and you can actually pass
them on to different processes.
And there might be some other different
requirements or some other
properties in there as well.
But
is this not a capability based system?
That's my question.
What's what's
in your if you missing, can
you use the capability based security
system to to secure or to
control entire process communication?
Um, well,
I think you're referring to the fact that
with there's also this thing that
it might be possible to sort of
steal tokens from a process where you can
say, I now want to sort of disallow
this process from accessing X,
and there is no
support for that at all.
So you start up a process and you granted
these tokens, but there's no way to
actually retract them later on that's
missing from this environment.
But if you just make sure that you start
your process up with the right set of
file descriptors where you don't leak
any things that the process shouldn't
have access to, then I think you should
already be quite cheap.
We have a question from Iasi, We are
a signal angel.
Yeah, how is this and rights
different from Dhaka, which is at the
end its base also only
true to stereo's
as I didn't understand the question
completely.
Do you hear me OK?
How is how is this rights
management different from Dhaka, which is
at its base also only
C.H. Road and tell you it's.
Um, so
I have to confess, there are a lot of
different operating systems out there and
all use capability based security in a
different way.
I think what cloud is what makes Cloud
API unique is that, first of all, it's
based on the POSIX APIs
for which there's already a whole bunch
of existing software available.
And compared to capsicum,
it has the advantage of sort of having
less food shooting.
So,
yes, there might be some other systems
that also sort of have a huge overlap in
functionality with this, but sort of.
Exactly. Focusing on making bosak stuff
work is actually where sort of the the
niche market is in this case.
We have a question from the microphone
from left
of most of the things
normally people today would do with
namespace.
So username spazzes,
network name spaces or
boundary lines and containers
like Takeda's screws up
only one thing which username
spaces which are coming soon
since two years now
and actually years as a kernel
hack.
To introduce username space into
the colonel has to touch
150 pieces
in the kernel and one of our developers
is working on this, but it's not
yet finished. So normally,
I would say if I have a critical
application, I would try to do
it and the user was a different user
and take away the rights of
this user.
And this is very similar to to this
kind of things of of of
CONTAINERIZE applications.
And I have all the.
All the things that I do not
even have to modify the application,
which might be hard, so if you have
to make you mention Java, give me a Java
binary which really accepts this file
descriptors, then
everybody would be happy.
But I've not seen that so far.
Yeah, so so I think that there
is sort of like a.
A divide or like like division
that sort of puts people into two camps
right now. So first of all, there is
this focus on switching towards
capability based systems, which I've
explained in this talk.
But then on the other hand, there's also
sort of a movement that's moving towards
virtualizing name spaces.
So that includes both FreeBSD jails,
but also DOCA and the entire Linux
namespace movement.
So my concern with
with the entire namespace
stuff that's going on in Linux and all
of the other systems in general is that
it actually removes transparency a lot
because, for example, the user ID user
credential namespace.
How annoying is that?
If you run, for example,
on on one system, you see that the
process is running as user 1000 and
then you just run inside
of that container or that single
namespace itself. And it turns out to be
one million and three.
It really removes transparency.
Also, the worst thing that you could even
come up with is pitting a bit
namespace virtualization, which is a
minefield not even needed, if you think
about it a bit more, because then the
problem becomes that like 75
in one environment is not 75
and another one. And it really
puts the Chernow's systems administrators
in might be a necessary reason why
this system tries to solve it by actually
cutting off excess fat instead of adding
more shrink wrap around it to sort of
make all the existing staff work.
There's this overly strong mindset
that for some reason there is no single
way we can ever change any applications
and userspace.
And I think that's a true shame.
I think, you know, times are changing.
Unix is already, what?
Forty years old?
Forty five years old by now.
Why can't it change?
That's that's really what I'm sort of
trying to experiment with here.
But but it's a really good market.
It's actually changing.
So if you put all
these things into a System D and you only
need to configure your system
properly and every rippin goes away
and then yes, most
people don't like System D, but yeah.
Yeah exactly.
Yeah.
Yeah. But I mean it's a it's a different
solution to, to, to solving a similar
problem. It's either by adding more
shrink wrapping around it in the kernel,
just, you know, adding more and more
virtualization or namespace
virtualization features in the kernel to
work around a problem or just
saying like we're going to remove stuff
and use the space that actually contradicts
with this model.
So it's two different mindsets.
Yeah.
We have time for one very brief question
from the front right microphone.
What does this mean for for scripting
languages in the shell?
Like if I if I work up a quick shell
script for automating something in the
file system, do I need to fiddle with the
capabilities to get it right or do I just
run it all powerful and lose the
advantages?
So
the unique shell is something that
is really something that's sort of
orthogonal to what I'm developing over
here. And I'd be amazed if
you ever get to the point where you
would just have a shell real like a born
like shell, a POSIX like shell, where you
can type in stuff that actually interacts
with cloud API programs.
Well, for
scripting languages, I think it's
actually different.
I mean, I'm
working towards having Python ported over
to this and then you actually have a
Python interpreter where you can just run
all your standard Python scripts in there
as long as they don't try to open
arbitrary files on disk.
And Python actually already has nice
interfaces for dealing with directory
file descriptors, for example, in the
latest versions of Python.
That is so, um,
it will break a lot of stuff.
I'm and that's why I'm saying it's
going to be a symbiosis and not like a
simulation. It's really two separate
environments and.
We'll see where it goes.
OK, thank you. Thank you very much, Ed
Colton.