Thursday, August 26, 2010

Malware and Virus Scans

So, a lot of my associates are Windows users out of necessity.

Got an email this morning:
"Our pc's fans started goin off again on full blast. We already did the virus detection and surprisngly it found viruses and deleted them. But today it started on full blast again. Any ideas?"

... Stop letting people use Internet Explorer? ;)

There's some .PDF, Flash, and JAVA vulnerabilities going around now; make sure you patch up your Adobe Reader and Flash Player to current, Update your JAVA to 6u21, run TFC.exe and then run a malware bytes scan.

After MBAM finishes cleaning up; go into the Windows Scheduled Tasks in control panel and remove any suspicious jobs (Lot of the nasty ones are untitled and look like a GUID like "{21EC2020-3AEA-1069-A2DD-

08002B30309D}")

Then fire up process explorer and kill off anything that doesn't have an entry in the Company Name field. (Kill *Any* Unsigned EXEs, even stuff from Logitech mouse drivers and Realtek audio controls)

Then fire up autoruns.exe and remove any suspicious startup entries. Heck, if you can, remove everything but the nvidia/ATI driver autoruns.

Now run TFC.exe once more to make sure all the tempdirs are emptied.

Alternatively, you can run an offline scan with a bootcd like AVIRA's Rescue CD -- the ISOs are updated weeklyish.

http://dlpro.antivir.com/package/rescue_system/common/en/rescue_system-common-en.exe

AVAST's also a good option.
http://www.avast.com/free-antivirus-download

Drupal on nginx

Just got an email from someone asking for my drupal config template, Ask and ye shall receive:

# Search and replace subdomain.fqdn.com with your domain info.
server {
listen 80;
server_name subdomain.fqdn.com;
access_log /var/www/sites/subdomain.fqdn.com/logs/access.log;
error_log /var/www/sites/subdomain.fqdn.com/logs/error.log;

# EXPERIMENTAL
#location / {
# root /var/www;
# index index.php;
# error_page 404 = @drupal;
#}
#
#location @drupal {
# rewrite ^(.*)$ /index.php?q=$1 last;
#}


# Set site_root
root /var/www/sites/subdomain.fqdn.com/public/;
index index.php index.html;

# Set doc_root (Drupal CleanURLs)
location / {
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
}
}

# hide protected files
location ~* \.(engine|inc|info|install|module|profile|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(code-style\.pl|Entries.*|Repository|Root|Tag|Template)$ {
deny all;
}

# serve static files directly
location ~* ^.+\.(jpg|jpeg|gif|css|png|js|ico)$ {
rewrite ^/favicon.ico$ /sites/default/themes/mytheme/favicon.ico break;
access_log off;
expires 30d;
}

# Install Imagecache module, update the location, enable this directive
location ^~ /sites/default/files/imagecache/ {
index index.php index.html;
# assume a clean URL is requested, and rewrite to index.php
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php?q=$1 last;
break;
}
}

location ^~ /sites/default/files/downloads/ {
index index.php index.html;
autoindex on;
}

# FastCGI Via Socket
location ~ \.php$ {
fastcgi_pass unix:/tmp/php-fastcgi.socket; #127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/sites/subdomain.fqdn.com/public$fastcgi_script_name;
include fastcgi_params;
}
}

# Proxy Via Socket or TCP
#location ~ \.php$ {
# proxy_pass unix:/tmp/php-fastcgi.socket; #127.0.0.1:9000;
# proxy_connect_timeout 15;
# proxy_redirect default;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# #proxy_set_header X-Forwarded-Proto https;
# }
}

### Redirect www to root domain?
#server {
# listen 80;
# server_name www.subdomain.fqdn.com;
# rewrite ^/(.*) http://subdomain.fqdn.com/$1 permanent;
# }

### Redirect root domain to www?
#server {
# listen 80;
# server_name subdomain.fqdn.com;
# rewrite ^/(.*) http://www.subdomain.fqdn.com/$1 permanent;
# }

### HTTPS server
#server {
# listen 443;
# server_name subdomain.fqdn.com;
# ssl on;
# ssl_certificate /var/www/sites/subdomain.fqdn.com/private/cert.pem;
# ssl_certificate_key /var/www/sites/subdomain.fqdn.com/private/cert.key;
# ssl_session_timeout 5m;
# ssl_protocols SSLv2 SSLv3 TLSv1;
# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
# ssl_prefer_server_ciphers on;
# access_log /var/www/sites/subdomain.fqdn.com/logs/secure.access.log;
# error_log /var/www/sites/subdomain.fqdn.com/logs/secure.error.log;
# location / {
# root /var/www/sites/subdomain.fqdn.com/public/;
# index index.php index.html;
# }
# location ~ \.php$ {
# fastcgi_pass unix:/tmp/php-fastcgi.socket; #127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /var/www/sites/subdomain.fqdn.com/public$fastcgi_script_name;
# include fastcgi_params;
# }
# }

Wednesday, August 25, 2010

Sometimes you must make the best of what you have available...

Super Armatrons rock in so many ways.




Every robot that you ever heard of normally employs some sort of individual servo mechanism for powering each joint of the robot. Not so with Armatron; There are no electronics inside at all, in fact the toy is entirely powered by a single motor. All of the toy's functions are controlled by a complex array of mechanical transmissions and gear trains. It's powered by 2 D batteries, directly connected to a power switch and a dinky brushed DC motor that looks to run around 300 RPM; it's very slow. Some clever folks have replaced the motor with a steam engine.







The Box, and the Manual (For posterity)


Yes, you are supposed to keep score yourself. :)



This toy has so many moving parts it almost defies verbal explanation. Shown above is an overview of the base mechanisms. Each of the two joysticks can be moved up/down, left/right and clockwise/counter-clockwise for a total of six movements of the arm. Each of the six movements is bi-directional. Four of the six movements are bi-directional with two speeds in each direction. The joystick linkages (orange parts) control six transmissions (black and white parts). All the transmissions are powered by a single motor on the right. The gearing above the motor is for a timing mechanism described below. The gearing and shafting behind the transmissions connect the transmissions to a series of ring gears described below.



There are three sections to the transmission system: (1) a row of six black forward gears, (2) a row of six black reverse gears and (3) a row of six white indexing drums. The picture above shows the lower row of forward gears without the other two sections of the transmission. The picture also shows how the forward gears drive the output shafting.


The picture above shows how the upper row of six reverse gears mesh with the lower row of six forward gears.



The picture above shows three of the six indexing drums. The red arrow indicates an inner gear fixed to the main drive shaft. One of the outer black gears is for high-speed operation. The other outer black gear is for low-speed operation. Friction between the gears causes the entire drum to rotate about the shaft unless the drum's position is held by one of five indexing tabs. Green arrows indicate four of the five tabs distributed around the drum. The tabs determine which of the two gears on the drum engages the forward or reverse gear. The combinations are slow-forward, fast-forward, slow-reverse and fast-reverse. The fifth index is neutral where no gears are engaged. Note how the left drum is thinner and has only one outer gear. This corresponds to the claw movements, which have only one speed in forward and reverse.



The images above show how the up/down movement of the right joystick controls the indexing of the rightmost drum. This corresponds to the up/down motion of Armatron's shoulder joint.



This picture shows the gear covers back in place. The arm assembly fits into the round ring gear socket. Armatron can continuously rotate through a full 360 degrees. This is made possible by the stack of ring gears. Each movement is transmitted from the base to the arm via a ring gear. The orange and back barrel is a timer mechanism that cuts power to the arm after the allotted time has expired.



Here are all the ring gears layered back in the socket.



This shot shows the underside of the arm assembly that fits into the socket of ring gears.

Here's some drawings of the mechanism ripped from the patents.








Thursday, August 19, 2010

Catching up with the configuration curve

Okay, so, I discovered some new stuff.

First: nginx can be convinced to do close-to-automatic deployments.

sudo tee /etc/nginx/conf.d/autoconfig.conf <<-\EOA
    client_max_body_size 5M;
    client_body_buffer_size 128k;
    proxy_connect_timeout 90;
    proxy_send_timeout 180;
    proxy_read_timeout 180;
    proxy_buffer_size 16k;
    proxy_buffers 8 16k;
    proxy_busy_buffers_size 32k;
    proxy_intercept_errors on;
    fastcgi_connect_timeout 60;
    fastcgi_send_timeout 180;
    fastcgi_read_timeout 180;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    fastcgi_intercept_errors on;
    include /var/www/sites/*/config/*;
EOA

Now when you drop a new site into /var/www/sites your configuration will be picked up after an 'reload nginx'! Just rename the config folder to config-disabled and reload 'nginx' to disable a site.

Second: PostgreSQL!

I'm sick of mySQL, Sun, and Oracle. Screw 'em all, time to jump ship to Postgres.
Yay for Drizzle and MariaDB; keep up the good work and don't let The Man (Oracle) keep you down. Maybe I'll come back from the pg-side, maybe not.

apt-get install postgresql php5-pgsql phppgadmin


This is a little more involved to setup than mysql, due to the lack of dbconfig-common support requiring manual setup.

nano /usr/share/phppgadmin/conf/config.inc.php


Now find and change the following line

$conf['extra_login_security'] = true;
to
$conf['extra_login_security'] = false;

and now all userids can login.

Now, postgresql itself comes in a locked down config out of the box.

sudo su postgres -c psql template1

ALTER USER postgres WITH PASSWORD 'securePassword!';
\q

sudo passwd -d postgres
sudo su postgres -c passwd

nano /etc/postgresql/8.4/main/postgresql.conf

Change the line:
#listen_addresses = 'localhost'
to
listen_addresses = '*'
and also change the line:
#password_encryption = on
to
password_encryption = on


nano /etc/postgresql/8.4/main/pg_hba.conf

Set up something like this: (IPv6 is used by default for some reason.)

# IPv6 local connections:
host    all         redmine_user         ::1/128               trust
host    all         all         ::1/128               md5

Easy way to do this is to highlight the ipv6 line, hit Ctrl-K, the up arrow, Ctrl-U, then change the 'all' username to 'redmine_user'.

service postgresql-8.4 restart

And you should be set.

mkdir -p /var/www/sites/phppgadmin/config

sudo tee /var/www/sites/phppgadmin/config/phppgadmin.conf <<-\EOA
server {
        listen 80 default;
        server_name localhost;
        access_log /var/www/sites/phppgadmin/logs/phppgadmin.access.log;
        error_log /var/www/sites/phppgadmin/logs/phppgadmin.error.log;

        location / {
            root /usr/share/phppgadmin;
            index index.php;
            }

        location ~ \.php$ {
            include /etc/nginx/fastcgi_params;
            fastcgi_pass unix:/tmp/php-fastcgi.socket;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /usr/share/phppgadmin$fastcgi_script_name;
            }
        }
EOA

rm /etc/nginx/sites-enabled/default
reload nginx

And viola, postgresql!

Wednesday, August 4, 2010

Weaving Redmine, RVM, Ruby, Rails, Rack, Thin, and nginx as a reverse proxy

Yesterday, it came down from On High.

Bossman say 'We need a trouble ticket system.' and Kami say "yes massa!"

A quick trawl of wikipedia's list later, and Redmine's the winner.
Time Tracking, Revision control integration, and full RBAC + lockdown, and all written in my favorite language, Ruby.

So, we'll be starting from where my previous post in the series left off.

You should have Lucid + nginx + php5-fastcgi + phpmyadmin set up already. (Honestly, you can skip the PHP stuff if you're not interested; I keep it around for Drupal and phpmyadmin.)

First: Get some required packages.

apt-get install curl patch git-core subversion autoconf build-essential bison libreadline6 libreadline-dev zlib1g zlib1g-dev libssl-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libmysqlclient-dev libpq-dev

Second, install rvm.
bash < <( curl -L http://bit.ly/rvm-install-system-wide )
tee -a ~/.bashrc <<-\EOA
[[ -s '/usr/local/lib/rvm' ]] && source '/usr/local/lib/rvm'
EOA
source '/usr/local/lib/rvm'

Disable ruby's documentation generation (Don't need it on rackspace; skip this if you're on a dev box.)
echo "gem: --no-rdoc --no-ri" >> /etc/gemrc

Install ruby 1.8.7.
rvm install 1.8.7

Now set it as the default.
rvm use --default 1.8.7

Get the sqlite3 gem compiled
gem install sqlite3-ruby
IF this fails, you're probably missing libsqlite3-dev

Get the mysql gem compiled
gem install mysql
IF this fails, you're probably missing libmysqlclient-dev

Get the pg gem compiled
gem install pg
IF this fails, you're probably missing libpq-dev


Install rack 1.0.1







gem install rack -v=1.0.1

Install rails 2.3.5




gem install rails -v=2.3.5

If you want the optional gantt chart generation, you'll need rmagick.
apt-get install libmagick9-dev imagemagick
That will pull down a bunch of -dev packages; now build the native extensions.
gem install rmagick

Now we need a better appserver than webrick. Let's go get thin.













gem install thin
Decide on where you'd like the redmine app to live; I like the private directory under the hostname.
mkdir -p /var/www/redmine.domain.com/private/ && cd /var/www/redmine.domain.com/private/

Now, checkout version 1.0's latest revision.

svn co http://redmine.rubyforge.org/svn/branches/1.0-stable redmine

Okay, we've got redmine; now to configure it. First, let's setup the database. Run this SQL in phpmyadmin:

create database redmine_core character set utf8;
create user 'redmine_user'@'localhost' identified by 'my_password';
grant all privileges on redmine_core.* to 'redmine_user'@'localhost';
Or phppgadmin: (Paste each line separately.)

CREATE ROLE redmine_user LOGIN ENCRYPTED PASSWORD 'my_password' NOINHERIT VALID UNTIL 'infinity'; 
CREATE DATABASE redmine_core WITH ENCODING='UTF8' OWNER=redmine_user;


Edit the config/database.yml and configure the database settings.
cd redmine/config/ && cp database.yml.example database.yml
production:
  adapter: mysql
  database: redmine_core
  host: localhost
  username: redmine_user
  password: my_password
  encoding: utf8

Or for Postgresql:


production:
  adapter: postgresql
  database: redmine_core
  host: localhost
  username: redmine_user
  password: my_password
  encoding: utf8


Now return to the redmine root (cd ..) and generate the session store.
rake generate_session_store

Now, we'll have redmine populate the database.
RAILS_ENV=production rake db:migrate

You'll be prompted to choose a language here; just hit enter for english.
RAILS_ENV=production rake redmine:load_default_data

Wooo! Let's test it.








ruby script/server thin -e production
Now visit port 3000. You should get a nice blank redmine instance.

Now, for configuring nginx for a reverse proxy test:
server {
        listen                  80;
        server_name             redmine.domain.com;
        access_log              /var/www/redmine.domain.com/log/access.log;
        error_log               /var/www/redmine.domain.com/log/error.log;
        root                    /var/www/redmine.domain.com/public/;

        location / {
                try_files       $uri @fallback;
                }

        location @fallback {
                proxy_pass              http://127.0.0.1:3000;
                proxy_connect_timeout   15;
                proxy_redirect          default;
                proxy_set_header        Host    $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                #proxy_set_header       X-Forwarded-Proto       https;
                }
        }
Okay, this works!

Next step: Setting up thin clusters on boot.
thin install

Set up the icky old init-scripts:
update-rc.d -f thin defaults

Now we can add YAML config files in /etc/thin/ !
--- 
pid: tmp/pids/thin-redmine.pid
group: rvm
wait: 30
timeout: 30
log: log/thin.log
max_conns: 1024
require: []

environment: production
max_persistent_conns: 512
servers: 2
daemonize: true
user: www-data
socket: /tmp/thin-redmine.sock
chdir: /var/www/redmine.domain.com/private/redmine 

Okay, let's start thin.
service thin start

And fix up our nginx proxy config:
upstream thin_redmine {
   server   unix:/tmp/thin-redmine.0.sock;
   server   unix:/tmp/thin-redmine.1.sock;
}

server {
        listen                  80;
        server_name             redmine.domain.com;
        access_log              /var/www/redmine.domain.com/log/access.log;
        error_log               /var/www/redmine.domain.com/log/error.log;
        root                    /var/www/redmine.domain.com/public/;

        location / {
                try_files       $uri @fallback;
                }

        location @fallback {
                proxy_pass              http://thin_redmine;
                proxy_connect_timeout   15;
                proxy_redirect          default;
                proxy_set_header        Host    $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                #proxy_set_header       X-Forwarded-Proto       https;
                }
        }

Enable your configuration and restart nginx.
service nginx reload
...

PROFIT!



Here's some links:



Monday, July 19, 2010

gPXE and the HTTP server that could

eBox 1.4 has support for serving a bootfile over TFTP.

Only it's broken. Oops.

Here's my quick fix:
sudo nano /etc/inetd.conf

Code:
tftp           dgram   udp     wait    root  /usr/sbin/in.tftpd /usr/sbin/in.tftpd -s /var/lib/tftpboot

That /var/lib/tftpboot is where tftp will serve files from.
eBox expects it to be serving a file such as:
/var/lib/ebox/conf/dhcp/eth0/firmware

Code:
tftp           dgram   udp     wait    root  /usr/sbin/in.tftpd /usr/sbin/in.tftpd -s /var/lib/ebox/conf/dhcp/eth0

Now when you 'upload' a new boot file to eBox's dashboard,
/var/lib/ebox/conf/dhcp/ethX/firmware
gets replaced with whatever you've uploaded.

But eBox won't set the dhcp-option 'filename' to serve it.

sudo nano /usr/share/ebox/stubs/dhcp/subnet.mas

Look for
Code:
% if(defined($info{'nextServer'})) {
                next-server <% $info{'nextServer'} %>;
% }
% if(defined($info{'filename'})) {
                filename "<% $info{'filename'} %>";
% }

And change it to

Code:
% if(defined($info{'nextServer'})) {
                next-server <% $info{'nextServer'} %>;
                # Filename entry added by Kamilion (dec 01 2009)
                filename firmware;
% }
% if(defined($info{'filename'})) {
                filename "<% $info{'filename'} %>";
% }

Now we need something to boot.

Go pick up the latest gPXE from here:
http://www.rom-o-matic.net/gpxe/gpxe-git/gpxe.git/contrib/rom-o-matic/build.php

Click Customize.

Change the following Settings:

[X] DOWNLOAD_PROTO_HTTPS
[X] DOWNLOAD_PROTO_FTP

[X] TIME_CMD
[X] DIGEST_CMD

And paste in the following Embedded Script: (Good base, but edit if you wish)
Code:
#!gpxe
echo "Greetings! Hit Ctrl-C to bail out."
sleep 5
echo "Going to DHCP on primary network adapter"
ifopen net0
dhcp net0
echo "Going to try http://netboot/default.gpxe"
chain http://netboot/default.gpxe
echo "Didn't work, we're still here. Falling back to http://boot/default.gpxe"
chain http://boot/default.gpxe
echo "Didn't work, we're still here. Falling back to BKO"
set 209:string pxelinux.cfg/default
set 210:string http://boot.kernel.org/bko/
echo "Here we go, off to boot.kernel.org!"
chain http://boot.kernel.org/bko/pxelinux.0
echo "Didn't work, we're still here. No Internet connection? Falling back to next BIOS Boot device"

You should get a single .pxe file back after clicking Get Image.

Go to DHCP -> Interface -> Advanced Options -> Thin Client.
Settings:
Next server: eBox
File Name [browse]
File path in next server:

Click "Change" to complete the settings, then Save Changes.

Place this file in the root of your HTTP server, named default.gpxe, and create a DNS alias to that machine named 'netboot'.

Code:
#!gpxe
imgfree
chain http://netboot/boot/menu.gpxe

Here's an example you can use to load Parted Magic:

Code:
#!gpxe
imgfree
kernel -n img http://bigblock/boot/pmagic/4.5/bzImage load_ramdisk=1 prompt_ramdisk=0 keymap=us loglevel=0 rw sleep=4
initrd http://bigblock/boot/pmagic/4.5/initramfs
boot img

Here's an example you can use to boot from iSCSI.

Code:
#!gpxe
imgfree
#dhcp net0
set keep-san 1
sanboot iscsi:10.10.10.250::::iqn.bigblock:storage.iscsikarmic-one
chain http://10.10.10.250/boot/iscsi.gpxe

More examples here: http://boot.sllabs.com/boot/

Friday, July 16, 2010

How to use u3-tool in Lucid

As my few blog visitors may be aware, I've been using the U3 customizer for windows for a long time on my 4GB cruzers to make them bootable.

http://blog.sllabs.com/2008/05/booting-heron-from-u3.html


I came across the u3-tool sometime ago when I bought my Clarion MiND, but I've only actually used it recently.

The U3 Customizer tools were released somewhere in 2005 and won't work in anything but windows XP 32bit, and won't recognize U3s over 8GB.



Gonzor discovered TwinMOS's application version supported Larger drives, Vista, and was released in 2007. However, the copy from TwinMOS didn't work for me -- and yet Gonzor's copy from mediafire did, both are version 1.0.5.5

I just bought an open-box 16GB Contour EXtreme with AES from newegg for $40, and it came yesterday.

So I started searching on how to hack a 16GB U3 drive.

"Oh, right, u3-tool... Almost forgot about that!"

In searching for 'how to use u3-tool', I ran across ubuntu launchpad bug report #534070 and played around a little.

I had some issues trying to get the windows version to work, I could resize the CD domain, but 'burning' the ISO failed consistently at 4-5% with a scsi error.

In Ubuntu Lucid, you can just 'sudo apt-get install u3-tool' but:
I was *NOT* able to get /dev/sg* or /dev/sr* to work -- I had to address the disk device itself as /dev/sdf to get it to work.

Hope this helps others out, as I think the major problem people are having is trying to use one of the /dev/sg like the u3-tool help text mentions.

Here's the log of the CD domain resize and burn I ran.

kamilion@SonyRA840G:~$ sudo u3-tool -i /dev/sdf
Total device size:   14.95 GB (16051601408 bytes)
CD size:             7.69 MB (8060928 bytes)
Data partition size: 14.94 GB (16043474944 bytes)
kamilion@SonyRA840G:~$ sudo u3-tool -l UbuntuLucid3264.iso /dev/sdf
CD image(1874288640 byte) is to big for current cd partition(8060928 byte), please repartition device.
kamilion@SonyRA840G:~$ sudo u3-tool -p 1874288640 /dev/sdf

WARNING: Loading a new cd image causes the whole device to be whiped. This INCLUDES
 the data partition.
I repeat: ANY EXCISTING DATA WILL BE LOST!

Are you sure you want to continue? [yn] y
kamilion@SonyRA840G:~$ sudo u3-tool -l UbuntuLucid3264.iso /dev/sdf
|**************************************************| 100%

OK

kamilion@SonyRA840G:~$ sudo u3-tool -i /dev/sdf
Total device size:   14.95 GB (16051601408 bytes)
CD size:             1.75 GB (1874329600 bytes)
Data partition size: 13.20 GB (14177271808 bytes)

After I changed the ISO, I also had to open Disk Utility (palimpsest), "Format the Disk"  to create a new MBR geometry, and then create a new NTFS partition.
(Which I've subsequently copied Windows 7's bootmgr to the root of the flash partition and ran "bootsect /nt60 U:", then copied the contents of the 7 install cd to the flash)
Both sections of the device are now bootable, the CD boots ubuntu lucid 32/64 TORAM=Yes, and the flash boots the 7 preinstallation environment.


(Yeah, I know the picture's screwed up -- I'll edit the blogspot CSS later.)

So that all worked just fine for me. Hope it does for you, too!

(And for the person who emailed me to ask about the background... It's from SSDD.)