Sébastien Wains

A blog about Linux, Open Source, VoIP and other geeky stuff.

Jun 18, 2015

Use this command:

openssl x509 -noout -in /etc/pki/tls/certs/client.crt -dates

Output would be:

notBefore=Feb 20 16:20:08 2015 GMT
notAfter=Feb 20 16:20:08 2016 GMT
Jun 18, 2015

I've used Chrome (and Chromium, depending on the platform, from now on I'll refer to it as Chrome) pretty much since it went out of beta.

I started to get annoyed with the last few versions though.

It all started as I tried to install an application on a Windows 7 machine (I'm not in an admin account at the time). That app contained malware not detected by the antivirus (I was not 100% confident it was clean though). It installed a couple of Chrome extensions that were redirecting traffic to ads and opening popups.

Trying to get rid of it has been challenging. If you removed the extension in the extension manager, upon next start up it would appear again. I tried Shield for Chrome but it wasn't helpful, it would just uninstall the extension but it would reappear upon the next restart. It is actually because Chrome was starting with some flags that were calling for extensions located on the filesystem. Run chrome://version and see the command line, you would see the directories called.

On the other hand, Chrome has been very good at removing an extension that Google considered "harmful". The extension is called "Download Youtube Chrome" (DYC), and you can only install it by downloading it from the web and installing it as an unpacked extension. Of course, this extension allows to download Youtube videos, so apparently copyrights are more harmful than actual malwares potentially spreading on thousands of machines.

Even before the DYC episode, I was using another extension allowing to download Youtube videos: "Video Downloader Professional". It was working great until Google decided to remove offending extensions from their store and by offending, they probably meant copyright offending (I commute a lot with poor reception, so I download videos for offline viewing).

And even before that, Google started to implement many new features that makes Chrome today twice as big as Firefox as (comparison based on OS X): profile management (chrome://flags/#enable-new-profile-management), OK Google voice search (this thing is listening to you constantly if enabled, and any OK Google record is saved in Google Cloud (you can delete them though)), desktop notifications.

You used to be able to specify where desktop notifications were supposed to appear, but Google decided to remove the feature, so you have to stick with notifications in the upper right corner of your screen, an area that you are very likely to click (Wi-Fi picker for example). I can't count how many times I have wrongly clicked on the stupid notification that just poped up in my face, triggering an action.

This goes along with default settings enabling translation and location (well, you get a popup asking if you want to share your location or if you want to translate the page), and those tend to slow down the browser considerably (I'm talking about a late 2008 Macbook here).

I had a couple of bookmarks synced in their "cloud" by signing in. I protected that with my Google password from that time, but today I have a new password and I still need to remind my old password whenever I install Chrome on a new machine. I haven't found how to manage that password (didn't search so much though, but it should be an obvious option).

Lastly, it has been reported that Chromium silently downloads binaries related to voice upon every start on Linux Debian. See http://www.theregister.co.uk/2015/06/17/debian_chromium_hubbub/ and https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=786909

So all in all, Chrome has become a memory hog, and Google is controlling your browser in a unprecedented way. The will push or remove whatever features or design, whenever they wish and don't care about what you think.

And if you believe that the supposedly open source project gives you a voice in the design and implementation, see this link talking about the decision to hide http:// from the URL bar when it's not secured by SSL: https://code.google.com/p/chromium/issues/detail?id=41467

See this comment particularly: https://code.google.com/p/chromium/issues/detail?id=41467#c19

Chromium UI design is not a democracy and is not based on users' votes ~ Peter Kasting

The problem with Chrome design is so important that some people even petionned against Kasting and the UI team: https://www.change.org/p/lawrence-page-replace-peter-kasting-and-the-google-chrome-ui-team

Well at least, they haven't given in on the new trend (started by Apple and Safari) to hide the path from the URL in the address bar. How soon though Peter?

I'm now switching back to Firefox, the last time I used it on a daily basis, it was version 3 or so. What is it now? Version 38. Holy cow, time flew.

If only Chrome was the only problem with Google.

Their are trying to force Google+ down our throats in the nastiest ways (you have to have a G+ account to upload Youtube videos, you can't comment Android applications without G+, etc.).

They shut down major applications like Reader probably in a way to increase traffic to G+, but it failed big time. They should have it at least integrated in G+, instead they lost those users.

iGoogle was neat too. Too good probably (my dad loved it), they had to kill it.

They are forcing Hangouts for people who still use Google Talk. Every once in a while, Gmail will switch to Hangouts without notice. Thanks, I'm now using competing products.

I'm done with the force-feeding attitude of Google that got so powerful that they think their vision of the web should be pushed (silently) to users. They know it, a vast majority of users just grasp things and don't question what they are presented with. They also have the right to pull the plug on popular services to serve their purpose of winning the social network business. Give up already Google, 90% of users never posted anything on your G+ toy: https://www.stonetemple.com/real-numbers-for-the-activity-on-google-plus/

Apr 29, 2015

Note: This has been tested on RHEL6 and Postfix 2.6.6 from RHEL repositories and version 2.10 from postfix.org. RHEL6 version contains a nasty bug, I recommend you use Postfix.org RPMS.

We want to route emails thanks to rewriting capabilities of Postfix.

An LDAP directory will provide us with an attribute.

We will use the "mailstop" attribute here. Different values can be defined: "brussels" or "stockholm".

An email would be relayed through this Postfix instance.

Examples:

Attribute = "brussels": john.doe@example.org would get rewritten john.doe@brussels.example.org
Attribute = "stockholm": john.doe@example.org would get rewritten john.doe@stockholm.example.org
No attribute or email address not present in LDAP : no rewriting

The LDAP configuration would be:

server_host = ldap.example.org
search_base = ou=some,ou=population,o=directory
query_filter = (&(mail=%s))
result_attribute = mailstop
result_format = %U@%s.%D
bind_dn = cn=login,ou=TechObjects,o=SYSTEM
bind_pw = password

We are taking the email address as input (%s). The value returned as output would be stored in the %s variable in result_format. We would construct the rewriten email address with the %U and %D variables (see postfix doc for details)

From now on, we can query the LDAP server and expect something like this:

# postmap -q john.doe@example.org ldap://etc/postfix/ldap.cf 
john.doe@brussels.example.org

Now, we are going to configure Postfix to actually rewrite addresses.

canonical_maps = ldap:/etc/postfix/ldap.cf

Then send an email to john.doe@example.org through that relay:

Apr 29 12:55:17 mx.intra.example.org postfix/smtpd[20276]: disconnect from mxin.example.org[192.168.96.200]
Apr 29 12:55:17 mx.intra.example.org postfix/smtp[20280]: 3A59580370: to=<john.doe@brussels.example.org>, orig_to=<john.doe@example.org>, relay=mx.brussels.example.org[192.168.96.4]:25, delay=0.08, delays=0.05/0.01/0.01/0.02, dsn=2.0.0, status=sent (250 Message queued)

We can see the address has been rewritten.

If the LDAP server is down, emails will be waiting in the maildrop queue.

If the LDAP gives several replies, Postfix will rewrite to the first result.

Apr 17, 2015

I bought a Synology DS214j a couple of months ago.

I bought only one 2TB disk in the first place. My plan was to buy a second disk a couple of months later so I would have a RAID1 array made of two disks with different mileage and probably different life expectancy. I set it up using the recommended option: "Synology Hybrid RAID (SHR)".

Personal opinion: I always believed that starting a RAID1 with disks from the same batch and more or less same production date is a recipe for disaster. They will start doing their job at the same time, will wear at the same rate and probably die around the same time. It is known that reconstructing a faulty RAID1 array can cause the second drive to die because of the long process of reconstruction and high read operations.

So back to the point of the article, adding a second disk to a SHR array...

For some reason, Synology made things confusing because of the vocabulary used.

You should stop the NAS, insert the drive. Start the NAS again, then go in "Storage Manager", where you would find a "Volume 1". Click on "Manage", and then you are presented with two options saying "Expand".

To me, "expanding" something is increasing its size. But by Synology dictionary, if you have a Synology Hybrid RAID (without data protection), and add a second disk to it, it will not expand the volume but will mirror the first drive.

(Merriam Webster tends to agree with me)[http://www.merriam-webster.com/dictionary/expand].

Apparently, if you have a 4 bay NAS, adding a second drive would actually start expanding the size of the volume. I cannot confirm this as I only have a 2 bay unit.

Conclusion: adding a second drive and "expanding" an existing "Synology Hybrid RAID (with no data protection)" actually results in "Synology Hybrid RAID (SHR) (with data protection of 1 disk fault-tolerance)". Don't worry, it won't turn into a RAID-0.

Thanks for making simple things confusing, Synology!

Feb 25, 2015

Tested with Active Directory 2003 and RHEL 7.0

For RHEL 6.0 see here

I consider that the server is correctly set up, its hostname should be set accordingly to the Active Directory domain. It should also be synchronised with NTP. A clock drift could cause issues because of Kerberos.

I assume an AD domain "EXAMPLE" (long name: intranet.example.org)

# host -t srv _kerberos._tcp.intranet.example.org
_kerberos._tcp.intranet.example.org has SRV record 0 100 88 srv00a.intranet.example.org.
_kerberos._tcp.intranet.example.org has SRV record 0 100 88 srv00c.intranet.example.org.
_kerberos._tcp.intranet.example.org has SRV record 0 100 88 srv00b.intranet.example.org.

Install the packages:

# yum -y install authconfig samba samba-winbind samba-winbind-clients pam_krb5 krb5-workstation oddjob-mkhomedir nscd adcli ntp

Enable the services at boot:

# systemctl start smb
# systemctl enable smb
# systemctl start winbind
# systemctl enable winbind
# systemctl start oddjobd 
# systemctl enable oddjobd
# systemctl start dbus

Edit /etc/krb5.conf:

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 default_realm = INTRANET.EXAMPLE.ORG
 dns_lookup_realm = true
 dns_lookup_kdc = true
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true

[realms]
 EXAMPLE.COM = {
  kdc = kerberos.example.com
  admin_server = kerberos.example.com
 }

 INTRANET.EXAMPLE.ORG = {
 }

[domain_realm]
 .example.com = EXAMPLE.COM
 example.com = EXAMPLE.COM
 intranet.example.org = INTRANET.EXAMPLE.ORG
 .intranet.example.org = INTRANET.EXAMPLE.ORG

Test Kerberos:

# kinit username@INTRANET.EXAMPLE.ORG
# klist

username should be domain admin in the Active Directory.

klist should gives this kind of output:

Ticket cache: FILE:/tmp/krb5cc_0
Default principal: username@INTRANET.EXAMPLE.ORG

Valid starting       Expires              Service principal
02/25/2015 15:23:30  02/26/2015 01:23:30  krbtgt/INTRANET.EXAMPLE.ORG@INTRANET.EXAMPLE.ORG
    renew until 03/04/2015 15:23:28

Delete the Kerberos ticket you just initialized:

# kdestroy

Edit /etc/samba/smb.conf:

[global]
workgroup = EXAMPLE
realm = INTRANET.EXAMPLE.ORG
security = ads
idmap uid = 10000-19999
idmap gid = 10000-19999
idmap config EXAMPLE:backend = rid
idmap config EXAMPLE:range = 10000000-19999999
;winbind enum users = no
;winbind enum groups = no
;winbind separator = +
winbind use default domain = yes
winbind offline logon = false
template homedir = /home/EXAMPLE/%U
template shell = /bin/bash

    server string = Samba Server Version %v

    log file = /var/log/samba/log.%m
    log level = 10
    max log size = 50
    passdb backend = tdbsam

[share]
    path = /home/share
    comment = Some cool directory
    writable = yes
    browseable = yes
    # there's a trust between EXAMPLE and EXAMPLE2
    valid users = username EXAMPLE2\username
    directory mask = 0777
    create mask = 0777

Restart Samba:

# systemctl restart smb

Join the domain:

# net join -S EXAMPLE -U username

It should work and you can then get information regarding the join:

# net ads info
LDAP server: 192.168.0.1
LDAP server name: SRV00C.intranet.example.org
Realm: INTRANET.EXAMPLE.ORG
Bind Path: dc=INTRANET,dc=EXAMPLE,dc=ORG
LDAP port: 389
Server time: Wed, 25 Feb 2015 15:27:05 CET
KDC server: 192.168.0.1
Server time offset: 0

Create the directory for AD users:

# mkdir /home/EXAMPLE/
# chmod 0777 /home/EXAMPLE/

Restart Winbind:

# systemctl restart winbind

Sources:

redhat.com

Feb 17, 2015

I just migrated this blog from Wordpress to Scriptogr.am.

Mainly because this blog isn't so much active anymore, those SQL IOPS were useless for something that had become so static (I disabled the comments many years ago, tired of spam).

I missed Posterous and started looking for something similar, until I found about Calepin.co and Scriptogr.am.

For those of you who don't know, Scriptogr.am will fetch markdown text files from your Dropbox and turn them into a website.

What I like about this approach is that all my articles are stored locally (in a readable format) on my computer, and I can grep, sed and awk the hell out of them.

On the Mac, I use Mou and on Android Draft. I still have to find a good editor on Linux.

Draft can connect to your Dropbox and synchronise with any folder, so you can pick your posts folder. Most similar apps don't give you a choice.

Mou has many interesting features and has integrated with Scriptogram, so you can push your articles straight from the editor.

The downside of Scriptogr.am is probably the lack of comments (which I don't care about, and some people came up with the code to have Disqus anyway), the inability to search inside your blog (you have to Google it), and the fact that if you need several blogs on the platform, you have to have as many Dropbox accounts. I can deal with that, I have a personal and work Dropbox account, I both use them for this blog and my travel blog.

I used exitwp to convert the XML export of Wordpress into markdown.

Now, you might actually start seeing new content now all over again, given how easy it is to publish stuff :-)

Feb 16, 2015

I use Terminator as my terminal app, and use the "watch for activity" feature a lot. With the following command, I'd get notified as soon as the connection is opened.

while ! nc -vz localhost 3306; do sleep 1; done
echo 'Database is available'
Feb 16, 2015

This command will allow you to pipe trafic generated by tcpdump on a remote machine into Wireshark running on your local machine:

ssh root@dest tcpdump -U -s0 -w - 'tcp port 389' | wireshark -k -i -
Feb 16, 2015

This has been tested on DCS-930L and DCS-5020L

<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>
<data version="1.25.0">
  <trigger type="wifi_connected">
    <useDefaultName>true</useDefaultName>
    <name>WiFi Connected: SSID</name>
    <enabled>true</enabled>
    <all>false</all>
    <ssidList>SSID</ssidList>
  </trigger>
  <trigger type="wifi_disconnected">
    <useDefaultName>true</useDefaultName>
    <name>WiFi Disconnected: SSID</name>
    <enabled>true</enabled>
    <all>false</all>
    <ssidList>SSID</ssidList>
  </trigger>
  <condition type="active_network_type">
    <useDefaultName>true</useDefaultName>
    <name>Active Network Type: Mobile</name>
    <none>false</none>
    <mobile>true</mobile>
    <wifi>false</wifi>
    <wimax>false</wimax>
    <bluetooth>false</bluetooth>
    <ethernet>false</ethernet>
  </condition>
  <action type="http_request">
    <useDefaultName>true</useDefaultName>
    <name>HTTP Request: POST https://webcam.public.url/setSystemMotion application/x-www-form-urlencoded ReplySuccessPage=motion.htm,ReplyErrorPage=motion.htm,MotionDetectionEnable=0,MotionDetectionScheduleDay=30,ConfigSystemMotion=Save store in motion</name>
    <url>https://webcam.public.url/setSystemMotion</url>
    <verifyCertificates>true</verifyCertificates>
    <basicAuthentication>true</basicAuthentication>
    <username>admin</username>
    <httpMethod>POST</httpMethod>
    <httpContentType>X_WWW_FORM_URLENCODED</httpContentType>
    <contentType>text/plain</contentType>
    <generalTextData></generalTextData>
    <formFieldList>ReplySuccessPage=motion.htm,ReplyErrorPage=motion.htm,MotionDetectionEnable=0,MotionDetectionScheduleDay=30,ConfigSystemMotion=Save</formFieldList>
    <timeout>60000</timeout>
    <storeInVariable>true</storeInVariable>
    <variable>motion</variable>
    <path>/storage/emulated/0/Download/file.bin</path>
  </action>
  <action type="http_request">
    <useDefaultName>true</useDefaultName>
    <name>HTTP Request: POST https://webcam.public.url/setSystemMotion application/x-www-form-urlencoded ReplySuccessPage=motion.htm,ReplyErrorPage=motion.htm,MotionDetectionEnable=1,MotionDetectionScheduleDay=30,MotionDetectionScheduleMode=0,MotionDetectionSensitivity=50,ConfigSystemMotion=Save store in response</name>
    <url>https://webcam.public.url/setSystemMotion</url>
    <verifyCertificates>true</verifyCertificates>
    <basicAuthentication>true</basicAuthentication>
    <username>admin</username>
    <httpMethod>POST</httpMethod>
    <httpContentType>X_WWW_FORM_URLENCODED</httpContentType>
    <contentType>text/plain</contentType>
    <generalTextData></generalTextData>
    <formFieldList>ReplySuccessPage=motion.htm,ReplyErrorPage=motion.htm,MotionDetectionEnable=1,MotionDetectionScheduleDay=30,MotionDetectionScheduleMode=0,MotionDetectionSensitivity=50,ConfigSystemMotion=Save</formFieldList>
    <timeout>60000</timeout>
    <storeInVariable>true</storeInVariable>
    <variable>response</variable>
    <path>/storage/emulated/0/Download/file.bin</path>
  </action>
  <action type="notification_status_bar">
    <useDefaultName>true</useDefaultName>
    <name>Notification on Statusbar: Webcam disabled House ID 2</name>
    <notificationIcon>HOUSE</notificationIcon>
    <title>Webcam disabled</title>
    <message>Motion disabled</message>
    <sound>false</sound>
    <vibrate>false</vibrate>
    <flashLED>false</flashLED>
    <flashLEDColor>#ff00ff00</flashLEDColor>
    <flashLEDOn>500</flashLEDOn>
    <flashLEDOff>500</flashLEDOff>
    <flagLocalOnly>false</flagLocalOnly>
    <flagOngoing>false</flagOngoing>
    <flagNoClear>false</flagNoClear>
    <notificationIDEnabled>true</notificationIDEnabled>
    <notificationID>2</notificationID>
    <priority>DEFAULT</priority>
    <visibility>PRIVATE</visibility>
    <messageBigEnabled>false</messageBigEnabled>
    <messageBig></messageBig>
    <largeIconEnabled>false</largeIconEnabled>
    <largeIcon></largeIcon>
  </action>
  <action type="notification_status_bar">
    <useDefaultName>true</useDefaultName>
    <name>Notification on Statusbar: Webcam enabled House ID 3</name>
    <notificationIcon>HOUSE</notificationIcon>
    <title>Webcam enabled</title>
    <message>Motion enabled</message>
    <sound>false</sound>
    <vibrate>false</vibrate>
    <flashLED>false</flashLED>
    <flashLEDColor>#ff00ff00</flashLEDColor>
    <flashLEDOn>500</flashLEDOn>
    <flashLEDOff>500</flashLEDOff>
    <flagLocalOnly>false</flagLocalOnly>
    <flagOngoing>false</flagOngoing>
    <flagNoClear>false</flagNoClear>
    <notificationIDEnabled>true</notificationIDEnabled>
    <notificationID>3</notificationID>
    <priority>DEFAULT</priority>
    <visibility>PRIVATE</visibility>
    <messageBigEnabled>false</messageBigEnabled>
    <messageBig></messageBig>
    <largeIconEnabled>false</largeIconEnabled>
    <largeIcon></largeIcon>
  </action>
  <action type="remove_notification_status_bar">
    <useDefaultName>true</useDefaultName>
    <name>Remove Notification on Statusbar: 2 (Automagic)</name>
    <automagicNotifications>true</automagicNotifications>
    <all>false</all>
    <notificationID>2</notificationID>
    <overall>true</overall>
    <packageName></packageName>
    <allOfApp>true</allOfApp>
    <filterNotificationID></filterNotificationID>
  </action>
  <action type="remove_notification_status_bar">
    <useDefaultName>true</useDefaultName>
    <name>Remove Notification on Statusbar: 3 (Automagic)</name>
    <automagicNotifications>true</automagicNotifications>
    <all>false</all>
    <notificationID>3</notificationID>
    <overall>true</overall>
    <packageName></packageName>
    <allOfApp>true</allOfApp>
    <filterNotificationID></filterNotificationID>
  </action>
  <action type="sleep">
    <useDefaultName>true</useDefaultName>
    <name>Sleep: 15s (allow device sleep)</name>
    <duration>15s</duration>
    <keepDeviceAwake>false</keepDeviceAwake>
  </action>
  <flow type="flow">
    <name>Webcam disable motion</name>
    <group>Webcam</group>
    <enabled>true</enabled>
    <lastExecutionStartTime>1417460412281</lastExecutionStartTime>
    <lastExecutionEndTime>1417460413698</lastExecutionEndTime>
    <executionPolicy>PARALLEL</executionPolicy>
    <triggercontainer id="t1" x="-70.0" y="87.5">
      <trigger>WiFi Connected: SSID</trigger>
    </triggercontainer>
    <actioncontainer id="t2" x="-70.0" y="262.5">HTTP Request: POST https://webcam.public.url/setSystemMotion application/x-www-form-urlencoded ReplySuccessPage=motion.htm,ReplyErrorPage=motion.htm,MotionDetectionEnable=0,MotionDetectionScheduleDay=30,ConfigSystemMotion=Save store in motion</actioncontainer>
    <actioncontainer id="t3" x="280.0" y="787.5">Remove Notification on Statusbar: 3 (Automagic)</actioncontainer>
    <actioncontainer id="t4" x="35.0" y="577.5">Notification on Statusbar: Webcam disabled House ID 2</actioncontainer>
    <connection from="t1" to="t2" type="NORMAL" sourcePosition="SOUTH" targetPosition="NORTH" />
    <connection from="t2" to="t4" type="NORMAL" sourcePosition="SOUTH" targetPosition="NORTH" />
    <connection from="t4" to="t3" type="NORMAL" sourcePosition="SOUTH" targetPosition="NORTH" />
  </flow>
  <flow type="flow">
    <name>Webcam enable motion</name>
    <group>Webcam</group>
    <enabled>true</enabled>
    <lastExecutionStartTime>1417459379523</lastExecutionStartTime>
    <lastExecutionEndTime>1417459399056</lastExecutionEndTime>
    <executionPolicy>PARALLEL</executionPolicy>
    <triggercontainer id="t1" x="-175.0" y="17.5">
      <trigger>WiFi Disconnected: SSID</trigger>
    </triggercontainer>
    <actioncontainer id="t2" x="-175.0" y="227.5">Sleep: 15s (allow device sleep)</actioncontainer>
    <conditioncontainer id="t3" x="-175.0" y="472.5">Active Network Type: Mobile</conditioncontainer>
    <actioncontainer id="t4" x="-175.0" y="682.5">HTTP Request: POST https://webcam.public.url/setSystemMotion application/x-www-form-urlencoded ReplySuccessPage=motion.htm,ReplyErrorPage=motion.htm,MotionDetectionEnable=1,MotionDetectionScheduleDay=30,MotionDetectionScheduleMode=0,MotionDetectionSensitivity=50,ConfigSystemMotion=Save store in response</actioncontainer>
    <actioncontainer id="t5" x="105.0" y="262.5">Notification on Statusbar: Webcam enabled House ID 3</actioncontainer>
    <actioncontainer id="t6" x="105.0" y="682.5">Remove Notification on Statusbar: 2 (Automagic)</actioncontainer>
    <connection from="t1" to="t2" type="NORMAL" sourcePosition="SOUTH" targetPosition="NORTH" />
    <connection from="t2" to="t3" type="NORMAL" sourcePosition="SOUTH" targetPosition="NORTH" />
    <connection from="t3" to="t4" type="TRUE" sourcePosition="SOUTH" targetPosition="NORTH" />
    <connection from="t3" to="t2" type="FALSE" sourcePosition="SOUTH" targetPosition="NORTH" />
    <connection from="t4" to="t5" type="NORMAL" sourcePosition="SOUTH" targetPosition="NORTH" />
    <connection from="t5" to="t6" type="NORMAL" sourcePosition="SOUTH" targetPosition="NORTH" />
  </flow>
</data>
Oct 10, 2014

In legacy versions of rsyslog, if you want to use the option PreserveFQDN, you have to set the option before anything else, or it wouldn't work.

If you are having issues sending logs from nxlog on Windows to rsyslog legacy, you might want to have a look at EscapeControlCharactersOnReceive.

http://www.rsyslog.com/doc/rsconf1_escapecontrolcharactersonreceive.html