Oh, do I need it? Okay, so good morning. Probably fresh from yesterday's walkabout. So we have a few minutes just to set up. So Jason, you've got about 50 minutes. So Jason is really going to give you a hands-on workshop on covering how to write SE Linux policies. And so you'll really go through the reference policy framework, which is, as it says here, but really it'll be like a hands-on workshop and kind of deep dive into the trade-offs and kind of how to define these policies and find applications. So what we're going to do is Jason's going to present up here for anybody who just joined. He also created some images, virtual machine images on here. If you want to pull those down on your own laptop to walk along with the session and kind of experiment. So if you need this, just raise your hand or kind of we'll pass it around. We're going to do this with video. So Jason, I think you're all mic'd up. I think so. Okay, so we're good to go. I will be running until the first session until close on 11 o'clock. Sounds good. All right. Can everyone hear me? All right. So this is SE Linux policy development. We're going to go over bits of the policy, how the policy is made, then the different parts of the reference policy, different main bits to like make writing policies easier. And then we'll at the end make our own policy for the little web server that's on the images I gave you. So who am I? I'm Jason. I'm a Jensu Linux developer. I look after the SE Linux policies on Jensu amongst all in the Hardin team. I recently also am an upstream SE Linux maintainer for that as well.  I probably won't put the VM image up because it's big and it's like super insecure on purpose, so probably not a good idea. Do you want the VM image? So a quick bit about SE Linux in general. SE Linux is secured enhanced Linux. So it's extra stuff on top of normal Linux that hopefully makes things more secure. It is different from normal permissions on like Unix permissions in that it's mandatory access. The normal Unix permissions are what's called discretionary access control DAC, which is up to sort of the user. You can set your own permissions on the files. You can set the user. You can change the group and stuff like that. And you can't do that with SE Linux. There's a global policy and you have to follow that. And it's loaded into the kernel and it will make sure it happens. It covers quite a lot of things. There's hooks into all parts of Linux. You can do networking parts. You can do regular files, access control, so a whole bunch of things. We'll get into some of that later. The base parts of the policy get loaded into the kernel when you boot. So if you look in slash EDC slash SE Linux strict, you'll see policy.31. That's the 31st version of the policy. So that's the current one. Then in context is a bunch of files that have the file contexts around different parts of the file system. So when you boot, the policy.31 is the file that actually gets loaded into the kernel. The other ones are used by user space to relabel things and check different things. So then this policy.31 is the one that's loaded. So where's that come from? That is built from lots of little modules that you have on your machine. On Gen2, they're stored in user share, SE Linux strict. There'll be a lot of .pp files. Those are one policy module per thing you want. So there's a Chromium policy, a Cron policy, cops, there's a lot of them. If you do SE module L like lists, there'll be a whole list of all of them. If you do list full, you'll see the different priorities. So if you want to override one of the system policies that's loaded in level 400, if you wanted to take Cron and add another rule to it, you could take the policy, keep the same name, add your own rules to it and load it in level 500, then it would mask the 400 level 1 when it gets loaded in. So you could write these things in raw SE Linux format, which is kind of verbose and kind of sucks. So everything uses RefPolicy, which is the reference policy not made for one specific distribution, but it's made sort of in general. So then all the other distributions take that policy and add on to it. Red Hat's policy is based off of this, GenC is based off this, Debian is based off that, but they'll have small changes for maybe if they move things around with file systems and things like that. RefPolicy is mostly M4 macros, so it's not the nicest, but you get used to it, so it's fine. And the way it's split is each policy file, or each policy is made of three files. There's the interfaces in adult IF file, and those are the ones that define how to use your policy for other... Like if you're the cron policy, you might want to allow other policies around the system, maybe like the log rotate and things that would run under cron. They would need a way to set up the transition from cron to their type. So you would use an interface from that. And then the .te file, I actually have it, I'm thinking out of order. Let's do this one. The .if file is the interface. The te file is the actual rules for that module, and the fc file is the file context for that one. So to label things on the disk later. Let's actually come back. Yeah. So permissions, the way allow rule is set up, you allow a certain type, access to another type, and then you give a list of permissions it's allowed to do, and usually you need a lot of permissions together. If you want to read a file, you can't actually just have read, you need to open the file first. So there's these defines which are set. So read file perms there will give you open permission and read inherited files. Read inherited files will give you get a file on that. So if you use this read file perms define, it just gives you everything you need. And everything underneath is usually safer. So read will be the one, like the most important one. And then manage will give you pretty much everything. Create, unlink, write, remove, all of the things on it. So the setup of these define is the permission that you're getting, and then the class and then perms at the end. So the permission will be, depending on what the thing is, it'll be like read, write, manage. If it's directory, you can have add, remove, these things. The class is different kinds of things like file versus sock file versus sim links. So if you look in the image that I gave, I put the whole policy source code in the roots home directory. So if you look in policy support, permsets, that's where all these are defined. So you can go find some more of them. And then on top of that there's patterns, which usually you need to do a whole bunch of things together more than just the permission. So if you need to read a file, it's inside a directory, so you need access to the directory first to be able to get the file. So if you want to just read the file, you need to search the directory. So if you want to create a file, you need to add an entry into the directory on top. So there's create file pattern, which will take three things instead of two. It will take the thing that wants to do it, and then it will take the directory and the file type because those might be different. You might have a file type, like a patchy log type, and then it might be in the directory, like var log type. So you can't just give access to the entire directory just because you need a file. So it's split up like that. And yeah, so you might have AppT gets to write files that are called AppLogT and they're in a directory called varLogT. Or if you want to read-write the socket file for MySQL, it will be in that directory and it's labeled that. These happen to be the same, but that is not always the case, so you've got to write out. And they take three parameters. The container is the middle one. And the domain is the source one who is running the thing, like your daemon or whatever your domain is. File trends are very important and also really complicated to get your head around in the beginning. They are without these. And there's also DOM trends, which is to change domain. But the transition basically starts you in one domain and you end up in another domain because otherwise everything would always be in one, which is useless. So you might have a transition from initT into ApacheT and then you would set a file transition. If you would set a transition in general, you might have when init runs a file called ApacheExecT, it'll end up with a process in ApacheT. And then file trends are what you encounter the most because usually the problems are file labels on disk. So if you want to have a file or directory called Apache and you want it labeled HTTP log2 and it's going to be in var log2, you can set a file trans pattern when HTTPD creates a directory and the directory is this parameter. When it creates it in this directory, it makes it into that label. So this pattern gives you only the bare minimum that you need on the parent directory so you don't get more than you need. And then it sets up the permissions to create the new directory. You can do this based on any file name, which is usually the case. There's also file name specific ones, which is useful if it's not needed that often but sometimes you'll have one demon creates many files in the same directory but they need to end up as different types. If you think like in it or something like that, it will need to create the PID files for different demons in a certain directory or maybe it's creating them in run and it needs to create run Apache, run MySQL and they need to be different types. So then you would create a named file transition on that specific name. It has to be a specific name. You can't do any reg access for this stuff. It has to be specific match only. No prefixes or anything. So it kind of sucks if you have stuff in temp because usually people in temp give things random names. They'll name it Dropbox Dash and a whole bunch of numbers. So it doesn't work at all for that.  But it's needed when you need it. So the policy modules, if you look in the home directory on the VM, I made a really simple MyAppT for a simple Python web server and it's split into three things. So the idea is basically every module should have its own stuff and only the module can access its own types directly. So that's why you need the interfaces. So if Apache wants to allow other people to read and write its log files, its log files are going to be called Apache log t or HBD log t. So other people can't use that type directly in their other ones. So they will call the interface instead and the interface will set up the rules they actually need. This allows if you need to change types underneath, you don't have to change every other module around. In general, the name of all the types and all the interfaces in the module should be named the same. Some modules are not as good at that as others. Apache is kind of a huge monster of a policy because a lot of different things the web server does, so it's kind of all over the place. Most of the types actually start with HDPD instead of Apache. So if you build it, you use the make file that RefPolicy puts on the system. I've actually sent a link to it in the VM, so it should just work if you just type make. And then you load the module in, so this like seModule-i Apache.pp, then it will load up the pp, like the policy module, into the whole list of all the other modules in the system, put them all together and then save it back as that policy. at all 31 file from the beginning, and then that gets loaded into the kernel. Interfaces, these are the ones I've been talking about all the time. They're named in general module name, verb, predicate. So Apache append log, or logging is the module for most things under var log and stuff like that. So if you want to file trans to the log type, or from the log type, brother, or GPG dump trans, this will allow appt to run GPG, and when it does so it'll run it in GPGT.  There's a lot of programs try to do things, but they don't actually ever need the thing, like they try to just get at it on like a lot of files, but they don't actually need access to any of them. So you could either give it the rule to make it shut up, or you can just tell it to shut up, and then it stops your logs filling up from all the other stuff. So occasionally one of these don't audits will hide something that's actually important for your... You try and run things, you don't see anything in the logs, but it still doesn't work. Then you can run semodule-db, and d will turn off all the don't audits in the entire policy, and then you will get really everything. It's quite overwhelming, but sometimes you need to do that. And then to turn them back on, you just semodule-db, and it will rebuild the whole policy again, and have the don't audits on. Finding interfaces. This is the hardest part. You pretty much have to... And you get them pretty quick after a while, but it does take a while to get used to. The names are pretty good in general. You can usually guess very close to what the name will be after seeing them for a while, but to help with this, there are these bash macros which will search the policy for things that you need. So if you want, for example, a file-trans for logs, but you don't know exactly what it's called, then you can se-find-if, file-trans, it's a regex, so dot-star instead of star, var-log. And then it will search through everything and it will say, oh, in logging.if, I found logging log-file-trans. And this is the line within that interface that matched what you searched for. And then there are more. I just cut them out from the slide. So you find that one, and that one looks like the right one. Then you can se-show-if logging log-file-trans, and it will show you the entire interface. So if you look at that one, and then you see, oh, there's a file-trans on log, and it also gives you symboling access, so that's probably the one you want. And then you can use that in your policy file. And se-find-if and find-def and se-show-if and show-def, because interfaces and defines are different places in the policy. So you... The defines are not very many of them, so they're pretty easy to know when something should be defined, so try that. Otherwise, it's always an interface. Booleans are another part of the policy. They're very important. And the basic idea is that different programs have lots of different features, but you don't always want to access all of them or enable all of them. So if you think about it, your web server might just serve static files. So you wouldn't want the web server to have access to anything else. The very basic case is it accesses, like, the var www.html, and only files in there it can read and nothing else at all. But then maybe you have, like, a MySQL server on the same machine, and then it's fine. It can access it over the SOC file. Then it wouldn't need any access. But maybe you have your MySQL server on another machine, in this case, then you need Apache to connect to, like, the database over the Internet. Then you can enable this hdbcannetworkconnect, and then it can connect over there. There's actually several Booleans. If you look at semanage Boolean-L, you'll see a whole list of them and the description for them. There's hdbcannetworkconnect, which gives you all network access. You probably don't want to use that one. Then there's hdbcannetworkconnect, db, there's memcache, specific ones that you'd probably want if you don't want to give it everything. Then the way you set these up in the policy is you first make the tunable, so you give the name of it, and then the false at the end is the default state for it. So refpolicy says that they should always be disabled. So use that for... If you want to choose whether to make it a negative or positive, it should be off by default, and it should... The default state will always be off, and then you can enable them as needed. Some distros... Red Hat enables quite a lot of them to make things work easier in the general case, in which case you might want to turn some off. Gen2 turns some on, but leaves almost all of them off. I don't know for Debian. Alright, so...  It's got a really simple Python script, which listens on port 8080 by default, and it saves its logs in barlog server somewhere. So, by default, I loaded the policy already. It should just work if you load it up, and then you can curl localhost 8080, and it'll give you some stuff out. Use search-m to look for ABCs, and recent... Recent is about the last 15 minutes. There's also a dash DS today, or something like that, if you want to get longer time, look at them, and then that's how I made and loaded the policy. So if you do that, you'll get it. If you instead do semodule-x500 to say the level 500 one, and then dash R, my app, it'll remove the policy. So if you do that, then the whole Python script will just, like, die. So, this is the VM. If I show you... Can you see that? Maybe not. Huh? No. I don't know how to do that. Yeah. Is that bigger? Yeah, it's a bit bigger. All right, so if we look at this, that's the... It's not very much. I took most of it from Stack Overflow. It saves the... It saves the logs into bylogserver.log, and it binds to port 8080 by default. So if you run this, and then on another one, if I curl, it gets a request. It's not very interesting the theme in itself. It's... So then if we look in... See Linux. These are the three files in it. So if we look at myapp.te, this is the policy that allows this script to work. The top, you define the type for the domain, and the type for the file. And in general, they're named myapp.te and myapp.exec.t. It's just sort of... It's not required, but it's sort of convention, so everyone kind of understands usually what they mean. Then this is an interface, which sets up all the really common operations you need. It will mark myapp.exec.t as a file type, so it can be on disk. It'll mark the other one as a domain, and it'll set up the transition from your normal user running it to allow it to run these things. And then there's the type for the log, and it's a log file. Then this needs to be able to do stream socket stuff for TCP. So this is a self rule, which means that the source and destination are the same thing. For some rules are like that, others are not, depending on what the thing are. Then if we go to these cornet rules, the cornet TCP bind generic and bind HTTP cache port. So this allows access on HTTP cache port type, which is port 8080. I did not actually give it access to HTTP port, like the main one. So if you try and run this script on port 80 instead, it'll die with permission denied. So if you want to see what the ports are, you s-e-manage port L, and then there's a lot of them. And you can grep through whatever you want. So if we look for there are HTTP cache port, which are these ones. There's HTTP port, which is 80443. Try, if you wanted to add also here bind HTTP port instead, and then load this up. Now if I run it, it'll actually bind to the port. So you can give it access on a per port type basis. There's another way, if a policy only gives access to a certain port, and you really want to bind a patchy to port 1234, you could modify the policy like that, or you can use s-e-manage port port. So there's s-e-manage port add, and you can add the protocol only TCP ports or port number 1234 would be given this HTTP port T, and then a patchy would be able to bind to it as well. What else? So if we look in it's not a very complicated policy, so the only context I set was on the main file of it, and it's named myappexectt. So that's the one that will let it know Let me try. Yeah, but this is dmware. Or this is this. Yeah, is that better? I don't know how to make it bigger. Oh well. Sorry, maybe you can move closer. So if you do ls-z, capital Z, then you get the context as well. Without is that. So these are the extra bits. Well, that's really small. It's labeled myappexectt, and this is the one that lets the transition happen. So if you instead change the context on this to just bint and set it. Now it's regular bint, and then you try and run the server, it's going to fail because regular bint means that you can just run it, but it doesn't do any transitions or anything. So if you fix up the if you put the file context back to what it should be then it works again. I only made a really small interface for this. Usually every module should have a role interface, which excesses that different roles need to use. So there's like regular users on the system will run under user t, and the sysadmin will be sysadm t. So there's different role policies as well. If you look in, there's a staff module, there's a user sysadm module, there's a user domain module. So each of these modules will call the role interface on all these other modules. And then give it access. I didn't do it properly on this one, I added it in itself like this, which you're not supposed to do. If you put it in the real policy, this line at the bottom should actually be in the staff module or in the sysadm module. But this keeps itself contained in this thing. And then we can go through some other of these interfaces. The use interactive FDs and the use inherited terminals. These are the ones to allow the module to print to your screen.  And it's kind of weird until you remember. Then this was the log transition. Pretty much what I explained earlier. It's quite a short module, so not that useful. This is the whole policy itself. So if you look in policy, if you look in policy support, there's all these different support macros. So these are the ones I mentioned earlier. First there's a whole bunch for different class sets which are like directory class. They're not used very much at all. Then these are the more useful ones. So these are get attribute on files, set attributes, and map the files, exact the files, append them, read, write, create. So there are a lot of these and they all follow the same naming convention. It's really easy to know what they're called. They're not just for files. On regular things, everything's kind of the same file, but there are different classes specifically for block files versus char files versus sockets. So if you give access to a file and somebody changes the file underneath, suddenly it needs to be a sim link, it doesn't work anymore. It's specifically kept separate for everything like that. So you need to keep in mind when you write the policy if people might be changing that to a sim link as well you might want to give that permission anyway. So most of the modules are under policy modules and there's a bunch of different ones. So if you look under contrib, there's a lot of these. So if we pick like there's a policy on chromium, it has first a whole bunch of booleans because maybe not everyone wants to run Java so you can turn that off. And then there's one to allow chromium to read USB devices if you have a UB key or something like that and that's off by default as well. And these are all the types and there's a lot of different things. Then we get to the optional policy part. So these things might not always exist in other systems since the policy is very modular, you can load only the modules you need. So if you don't have cups loaded on your system this cups read config and cups stream connect, those two interfaces require cups to be present. If it's not loaded, those two will fail. So this optional policy block means that it will check all those interfaces that they require and if it doesn't like if the requirements aren't matched it takes the whole block out. So you can use cups like that. So the debus one there's access for all the different debus things altogether. So if they don't work it doesn't keep part of them, it'll knock out the entire block not just part. There's also if deaths, if you need to set the they're kind of like tunables but they're set during build time so user can't change those. So you have to use them because you can't use a tunable everywhere but try not to use them and try to use tunables instead because they're better. Are there any questions or something in particularly want to see or do or so if I'm deploying a server or something so should I start up with is there been only one interface that can set the ones I need or what do you call it? Red Hat enables a lot of them because they don't know exactly what you're going to use so they want the general case to work. There are some Booleans which you may want to look at. There's something like allow Kerberos which Kerberos requires network access for everything that uses Kerberos. So if you don't use Kerberos you probably want to turn that one off. I don't know if they have it on or not by default but if they do because you might use Kerberos for logging in so then you obviously want to keep it off but you don't just turn everything off but you can read the descriptions for them SeManage this command Boolean-L will list all the names of them the description over here and the on off thing is there's two ways to set it. You can set it permanently in the policy so it'll happen every time you reboot it'll be back to that state then you can set them on and off only now but they're not saved in the policy so the next time you reboot it'll be back to what it is by default. So there are some like there's this secure mode policy and insmod and policy load if you turn that one off if you turn that one on then you can never reload the policy at all like it removes all the permissions to allow you to reload the policy the only way to reload that one is to reboot so it's disabled and then load it again so if you have a really secure system you might want to set things up, make sure they're all working and then flip that one on but you probably want to set it on boot every time because if you set it permanently then like disabling it's a real pain in the ass and you don't want to just turn off everything because there's for example global SSP is the one to allow every domain to access you random because you need it for the stack smashing canaries so if you turn that one off then it's worse than on so don't just like turn everything off it's not the right answer but you do read through them maybe you want to like grep for on and see which ones are on and then maybe decide if you want to turn them off or yeah like console login that's probably not something you want to turn off either because otherwise you can't login your machine anything else how do you test your policies oh that's a thing I completely forgot how do you test your policies yeah thanks I completely forgot to explain that mainly you write the policy and run it and then so if I if I remove the policy for this thing I wrote now it just won't work at all if I because it doesn't know what it was like it was something and now that type is gone so now it's unlabeled so if I run server it won't even let me run it because you have no access on unlabeled it's like I don't know what the thing is so you can't do it is this just a pull it from strict yeah strict not targeted so if I make it like this it won't work so then usually you start by making the base thing set up its own type for the thing that you want and do that part and then I can actually just remove stuff here so if I remove like all these network parts and then label it again it sickles so that's not very useful then you can run audit to allow which will read through your audit logs and convert the lines into like a policy thing so this one saying it needs access on dinty the other way you can do is this AU search this line AU search dash M ADC dash TS recent so this lists all the lines in the last 15 minutes that have happened so if you look here somewhere there'll be this one is user local bin server it's trying to do all these different things this is the file this is the program this is just trying to do it this is the directory of the programs in you get the denied map at the bottom so the audit logs are very verbose and they're very very good for finding out what happened in the system so you run the audit demon and it collects everything all the SC Linux denials and errors and everything go into the audit log but not just SC Linux it collects a lot of things from the whole system you can even set up audit to look at a certain directory and tell you if anybody writes the directory for any reason whatsoever so if you really need to know certain things audit is very powerful so if you look at this and you'll see what the denial was and then you go oh okay I need to add that back then we add that one now load the policy again and try and run it and now you get a different error so writing the policies is very much an iterative approach one way you can do it is just turn off you could turn off SC Linux completely and run it and then see what the audit logs say and then add everything but that's a very bad way to do it because a lot of the time you don't actually need some of the permissions like some programs for whatever reason maybe we'll search a bunch of other files which are completely not needed for their operation but they just happen to do it anyway so if you do it in permissive mode you'll just add all the rules which is the wrong way to do it if you do it instead in enforcing mode it'll hit one denial and that'll be the one that makes it stop you add that one and then keep going then you'll get that still lets it run which is what you're aiming for and audit is your friend it has a whole bunch of features so look into that I think if you can do that you've solved the halting problem so probably not there are that's why we have the interfaces because the interfaces, there's a lot of things that come together a lot of the time so it's pretty obvious if you need to access the network you need to do all these other things too so you just use the interface and it will grant you the other permissions that almost always come along with it so definitely use the interfaces and don't use these rules wrong because then you'll miss some of them or the interface will give you the lock and the iOctal permission even though maybe you don't need it now but maybe later something changes and then you need to redo all your stuff so just use the interfaces and they cover most things and then you just need to look in bigger blocks instead of each granular individual permission because that gets really tiring otherwise um anything else I guess that's it any other questions to Jason kind of getting towards the end of our time so any last opportunities to ask yeah okay so Jason great to have you thank you I'll put the slides up on my blog after maybe tomorrow or something alright that's all so this is the cyber security track love that for sure we've got the next session starting about 11 o'clock so we've got about 5 minutes to settle in we'll continue from there thank you Jason just there already welcome to Foss Asia so a Saturday track what we've got is the cyber security topic the cyber security track that we're covering here so just in between we've got a lightning session with some of the students so really there from the United World College of Southeast Asia they're kind of a group focusing on ethical hacking and so really nurturing the interest and the kind of participation in cyber security