If you want to just redirect STDERR to tee, run the following command.
some-command 2> >(tee /var/tmp/output)
Principal Software Engineer/Architect, motorcyclist, drummer, and artist
If you want to just redirect STDERR to tee, run the following command.
some-command 2> >(tee /var/tmp/output)
Following is a quick how-to on compiling and adding addition SELinux modules.
When configuring and deploying new and/or custom services on systems that are enforcing SELinux you will likely have to compile addition SELinux modules.
This how-to includes how to go through each step of compiling a new module one-by-one; similar to the model of breaking down the compilation of C and C++ into it’s composite steps.
Step 1: Gather the audit.log entries
You will need to determine which action(s) that SELinux is blocking. To do so, you can tail the /var/log/audit/audit.log file. You will see something similar to the following
type=AVC msg=audit(1517605342.101:88032): avc: denied { write } for pid=7236 comm="check_zookeeper" path="/tmp/sh-thd-1517587323" dev="dm-0" ino=308042 scontext=system_u:system_r:nrpe_t:s0 tcontext=system_u:object_r:tmp_t:s0 tclass=file
type=SYSCALL msg=audit(1517605342.101:88032): arch=c000003e syscall=2 success=no exit=-13 a0=1e2df10 a1=2c1 a2=180 a3=0 items=0 ppid=7232 pid=7236 auid=4294967295 uid=997 gid=994 euid=997 suid=997 fsuid=997 egid=994 sgid=994 fsgid=994 tty=(none) ses=4294967295 comm="check_zookeeper" exe="/usr/bin/bash" subj=system_u:system_r:nrpe_t:s0 key=(null)
type=PROCTITLE msg=audit(1517605342.101:88032): proctitle=2F62696E2F62617368002F7573722F6C6F63616C2F6E6167696F732F706C7567696E732F636865636B5F7A6F6F6B65657065722E7368002D2D73746174
Take that output and save it into a file.
Step 2: Generate the Type Enforcement (te) File From the Log Output
audit2allow -m new-module > new-module.te < audit-log-output
Step 3: Check and Compile the SELinux Security Policy Module (mod) File From the .te File
checkmodule -M -m -o new-module.mod new-module.te
Step 4: Create the SELinux Policy Module Packet (pp) File From the .mod File
semodule_package -o new-module.pp -m new-module.mod
Step 5: Install the SELinux Policy Module
semodule -i new-module.pp
There are a number of tutorials online for adding a new disk to a machine and then extending an existing LVM partition to use the new device.
This particular tutorial covers the use case of adding a new disk to a Linux server and then creating a NEW LVM partition on it without modifying the existing devices and LVM partitions.
The first thing you will need to do is add the physical device to the server (or VM).
Then, you need to confirm that the OS can ‘see’ the device. The following command will show you the list of avaiable disk devices.
# fdisk -l
Disk /dev/sdb: 80.5 GB, 80530636800 bytes, 157286400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Here, we see that the OS can ‘see’ the /dev/sdb device. For the rest of this tutorial, we will assume that your new device is /dev/sdb.
Using fdisk, create a primary partition on the new device
# fdisk /dev/sdb
Welcome to fdisk (util-linux 2.23.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0xc78ce5fd.
Command (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): p
Partition number (1-4, default 1):
First sector (2048-157286399, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-157286399, default 157286399):
Using default value 157286399
Partition 1 of type Linux and of size 75 GiB is set
Command (m for help): w
The partition table has been altered!
Calling ioctl() to re-read partition table.
Syncing disks.
After partitioning re-run fdisk to list the partitions
# fdisk -l
Disk /dev/sdb: 80.5 GB, 80530636800 bytes, 157286400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0xc78ce5fd
Device Boot Start End Blocks Id System
/dev/sdb1 2048 157286399 78642176 83 Linux
Now, create an LVM Physical Volume (PV)
# pvcreate /dev/sdb1
Physical volume “/dev/sdb1” successfully created.
Create the LVM Volume Group (VG)
# vgcreate centos_repos /dev/sdb1
Volume group “centos_repos” successfully created
Execute the vgdisplay command to list all of the Volume Groups
# vgdisplay
— Volume group —
VG Name centos_repos
System ID
Format lvm2
Metadata Areas 1
Metadata Sequence No 1
VG Access read/write
VG Status resizable
MAX LV 0
Cur LV 0
Open LV 0
Max PV 0
Cur PV 1
Act PV 1
VG Size 75.00 GiB
PE Size 4.00 MiB
Total PE 19199
Alloc PE / Size 0 / 0
Free PE / Size 19199 / 75.00 GiB
VG UUID FDgd3y-keqV-riq6-vb46-C2F5-JJa2-Ew2DW4
Create a LVM Logical Volume (LV). In this case I am going to use the entire drive
# lvcreate -n repos –size 74.9G centos_repos
Rounding up size to full physical extent 74.90 GiB
Logical volume “repos” created.
lvdisplay will list all of the existing Logical Volumes
# lvdisplay
…
— Logical volume —
LV Path /dev/centos_repos/repos
LV Name repos
VG Name centos_repos
LV UUID pvNLX4-3wTf-2eMY-RebF-WnFU-8y9F-BRidMn
LV Write Access read/write
LV Creation host, time nebula, 2017-10-20 17:36:38 +0000
LV Status available
# open 0
LV Size 74.90 GiB
Current LE 19175
Segments 1
Allocation inherit
Read ahead sectors auto
– currently set to 8192
Block device 253:4
Now we need to format the LV. In this case we will use ext4, you may choose another filesystem format. Be sure to use the LV Path returned by lvdisplay.
# mkfs.ext4 /dev/centos_repos/repos
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
4915200 inodes, 19635200 blocks
981760 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=2168455168
600 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424
Allocating group tables: done
Writing inode tables: done
Creating journal (32768 blocks): done
Writing superblocks and filesystem accounting information: done
Now you can mount the file system as usual and/or add it to /etc/fstab.
I am working on a VM that is running GNOME under RHEL 7 and I typically run with 12 workspaces. The default GNOME install only has the keyboard shortcut configurations up to “Switch to workspace 4”.
It turns out that the solutions is to use the gsettings cli tool to add additional shorcuts.
$ gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-5 "[\"<Control>F5\"]"
$ gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-5 "[\"<Alt>5\"]"
Or, otherwise know as: SELinux and Silent Denials.
Sometimes when troubleshooting SELinux issues, you will have added new policies for each of the denial causes written to the audit.log, but SELinux will still be denying access . . . and not giving you any further information about it in the audit.log.
Various processes often execute additional system calls that are above an beyond what they need to do for normal operation. Many of them are blocked, and in order to keep filling the audit.log with harmless denials they are silently dropped. These are defined by a set of dontaudit rules.
In order to temporarily disable them, issue the following command as root
# semodule -DB
The -D option disables dontaudit rules and the B option will rebuild the policy. After this runs, you should see additional information in the auditlog and with that information use audit2allow -i input-file -M output-file to build your .te and .pp files.
After debugging is complete run the following to re-enable the dontaudit rules.
# semodule -B
In order to be able to access a Samba share on a remote client as a mounted file system execute the following command, as root on the client:
mount -t cifs -o user=<user-on-samba-share>,uid=<uid-on-local-macheine>,gid=<gid-on-local-machine>,rw,workgroup=<your-workgroup> //ip/share /mnt/mount-point-dir
You will be prompted for the password for the user defined on the Samba server.
If you are able to authenticate, and then get the following error:
ls: reading directory .: Permission denied
Check the SELinux context type of the directory on the samba share. It should be samba_share_t
This is one of those things that I tend to do on a regular basis . . . but unfortunately don’t remember the details each time, so I am adding it for future reference.
Often, developers will want to mock static methods that return void. The Mockito and PowerMockito frameworks provide for this, but the syntax isn’t immediately obvious.
Following is an example.
public class SomeClass {
public static void doSomething(String arg1, int arg2) {
// Method that does something...
}
}
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
/*
* The RunWith and PrepareForTest annotations are following annotations are
* necessary to mock the static methods in the SomeClass class. The RunWith
* enables the class to be run via PowerMock, and the PrepareForTest is an array
* of the classes with static members that we want to mock.
*
* The PowerMockIgnore annotation tells PowerMock to defer the loading of
* classes with the names supplied to the system classloader. This will vary
* depending on the dependency tree that you are using/testing. It is also
* not necessary, but here for example purposes.
*/
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({
"javax.management.*",
"javax.net.ssl.*",
"org.apache.log4j.*"
})
@PrepareForTest({ SomeClass.class })
public class SomeTestClass {
@Test
public void shouldDoSomethingExpected() throws Exception {
// Set up the SomeClass's static members for mocking
PowerMockito.mockStatic(SomeClass.class);
// Configure the mock for the method in question.
// The following syntax is what is key here
PowerMockito.doNothing()
.when(
SomeClass.class,
"doSomething",
Mockito.anyString(),
Mockito.anyInt());
}
}
If you are building a Java program that requires the ability to execute native commands on the machine which require sudo it requires some additional considerations other than just writing the Java code.
The problem is that sudo, by default, requires a tty for executing sudo such that a password can entered. Even if you configure sudoers to grant NOPASSWD access to a specific command you will still get the following error
sudo: sorry, you must have a tty to run sudo
In my case, I was writing a set of integration tests in Java that needed to be able to start and stop a service to run a test.
I settled on adding an additional sudoers config file in /etc/sudoers.d. This ended up be the cleanest and most encapsulated change that did not then require any special considerations in the Java code.
The change simply involved adding a file with the following contents to /etc/sudoers.d which indicates that running sudo for the rchapin user does NOT require a tty and then grants access to the specific commands.
Defaults:rchapin !requiretty
rchapin ALL=(root) NOPASSWD: /bin/systemctl stop rabbitmq-server.service
rchapin ALL=(root) NOPASSWD: /bin/systemctl start rabbitmq-server.service
A common design pattern is to define a class or list of classeses in configuration such that at runtime the classes can be dynamically instantiated.
I’ve done this before in many other languages and had need to do so today in Python (2.7.11)
It seems as though the clean way to do so is by using the Pyton importlib module. By using it, it enables you to cleanly dynamically import sub modules
Following is an example:
import importlib
klass_1_module = 'some.module.name'
klass_1_classname = 'KlassNameOne'
klass_2_module = 'klass2module'
klass_2_classname = 'KlassNameOne'
Klass1 = getattr(importlib.import_module(klass_1_module), klass_1_classname)
klass1_instance = Klass1()
Klass2 = getattr(importlib.import_module(klass_2_module), klass_2_classname)
klass2_instance = Klass1('some_arg')
If you are using Mockito and PowerMock to build mocks for your Java tests and you run into the following error:
2016-05-05 17:31:20,204 main ERROR Could not reconfigure JMX java.lang.LinkageError: loader constraint violation: loader (instance of org/powermock/core/classloader/MockClassLoader) previously initiated loading for a different type with name "javax/management/MBeanServer"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:238)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:182)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:70)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Simply add the following as a class level annotation:
@PowerMockIgnore( {"javax.management.*"} )