Uncategorized – Cedric's Cruft http://www.ce3c.be Yet another blog about ... stuff. Fri, 04 Jul 2014 23:13:03 +0000 en-US hourly 1 https://wordpress.org/?v=5.1.12 Using a Raspberry Pi as a WiFi repeater http://www.ce3c.be/256-using-a-raspberry-pi-as-a-wifi-repeater/ http://www.ce3c.be/256-using-a-raspberry-pi-as-a-wifi-repeater/#comments Sat, 08 Jun 2013 21:40:22 +0000 http://www.ce3c.be/?p=256 I don't have internet, argh!

The things a person would do for WiFi

Running airmon learns me that there are 20+ discoverable networks in the neighbourhood. Too bad that they're all WPA2-protected, of VERY poor signal strength, and have no detectable associated clients. People in France have some special modemrouters that are called livebox'es and freebox'es. They are WPA2 protected by default with insane passwords like 9997AD9E3E13A6DD79E6C77241. This is a 26-character hex string: it makes me wonder if this password is some sort of hash of a few customer specific properties (eg. client ID) rather than being randomly generated. Anyhow, even if I manage to capture a WPA handshake, I would still need a dictionary with 16^26 entries (4.36e+22) in order to crack it succesfully (provided that that person hasn't changed the login). Hypothetically of course, because WiFi hacking is illegal.

Mind you: of course I went knocking next door, but I couldn't find someone with an AP that is reachable by me. Except for Bart's ...  strangely I'm still able to capture his WiFi although he lives in a different wing of the residence... And by "being able to capture" I mean taking the laptop in my hands, go stand at the doorstep about 6 meters away from my desk, and tilt it in the right direction.

Don't throw away old hardware

When it comes to technical devices, I'm a hoarder. It might be the only good explanation why I brought my old HTC HD2, my old Nokia 3120c, a Raspberry Pi, and an old D-link DI-524 with me to France. Knowing that I can capture WiFi at the doorstep, I was thinking how I could use all of those things to make some sort of WiFi repeater so I could access Bart's internet at my desk.

I tried a few setups:

WiFi → HD2 → Bluetooth → Laptop

The HTC HD2 captures the WiFi signal at the doorstep, and has a bluetooth DUN server running (BlueDUN). I would then be able to connect my laptop using bluetooth to the HD2. Sadly the desk was too far away for bluetooth to work fast and reliable.

WiFi → HD2 → USB → Raspberry Pi → Ethernet → DI-524 → WiFi → Laptop

The HTC HD2 captures the WiFi signal at the doorstep, is connected via USB to the Raspberry Pi. Then the Raspberry Pi is connected via Ethernet to the old D-link router, which I will connect to via WiFi. Sadly the old D-link router didn't appear to work anymore (it sort of did until I put it in a different subnet, but now all of a sudden it won't boot anymore, can't be reset anymore, and basically turned into a piece of garbage).

Since the DI-524 was dead, I connected the Raspi directly to my laptop via Ethernet. Now how does this setup work?

WiFi → HD2 → USB → Raspberry Pi → Ethernet → Laptop

Setting up the devices

The HTC HD2 still had a WP7 ROM on it. Since I know my way a bit better with Android, I flashed it a NAND ROM called "Sense of Eclipse".

After booting it up, native USB tethering seemed to be not working.

I tried a  different approach: a tool called Azilink, which is basically an implementation of an OpenVPN server for Android. I would have to run the OpenVPN client on my laptop, while tunneling the connection through the RasPi. The RasPI needed an ARM-compiled version of the Android debugging tool "adb" (you may find a precompiled binary at XDA). Surprisingly, the RasPi had no trouble recognizing the USB device, and I was able to forward the tcp ports. Sadly Azilink crashed each time after succesfully tunneling a few 100 bytes.  Their bugtracker on google code is full of messages, but they all remained unanswered.

So for a few days I had a working solution:

On the HD2, there was a SOCKS proxy server running on port 5555. Again with the adb-tool from XDA, I executed "adb forward tcp:5555 tcp:5555". This would make the proxy server port locally available on the Raspberry Pi on port 5555. I was now able to connect from my laptop using SSH "ssh -L5555:localhost:5555". Now all that is left, is making the browser use the SOCKS server at localhost port 5555.

Using Proxifier or SocksCap (which forces all your connections to go through the proxy), it becomes a bit easier. I still didn't have UDP though

Although I had internet now, it remained a pain to be bound by the Ethernet cable: I wasn't able to sit at my desk. The easy solution may be buying an extra Ethernet cable, but I decided to buy a WiFi dongle from LDLC instead that can be put into access point mode. I bought the D-link DWA-121, which is a dongle that is said to work with the Raspberry Pi.

A WiFi repeater

WiFi → HD2 → USB → Raspberry Pi → (USB) WiFi

Now we arrive at the real thing: an actual WiFi repeater.

First of all, I installed a new ROM on the HD2 that had working native USB tethering (NexusHD2-CM9). This way, I would be able to eliminate the SOCKS server and turn the Raspberry Pi into a WiFi router. Running speed tests on the HD2 now showed that the WiFi connection was wonky. I couldn't find the "Improve Wi-Fi performance" mode in the settings, so installed an app from the market called "WIFI High Performance". This improved WiFi latency and speeds drastically. I now enabled native USB tethering.

Using the adb shell, I found out that USB tethering was enabled on a new subnet 192.168.42.0/24, with the HD2 having 192.168.42.129 as IP.

root@raspberrypi:/home/pi# adb shell
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
# ip route
192.168.1.1 dev wlan0 scope link
192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.17 metric 314
192.168.42.0/24 dev usb0 proto kernel scope link src 192.168.42.129
default via 192.168.1.1 dev wlan0

With the WiFi dongle plugged in, and with the newly available usb interface on the Raspberry Pi, I had the following interfaces available:

root@raspberrypi:/home/pi# ifconfig -s | cut -d' ' -f1 | tr '\n' ',' | sed 's/,\(.*\),$/s: \1\n/'
Ifaces: eth0,lo,usb0,wlan0

With usb0 being the connection to the HD2 and wlan0 being the WiFi dongle, I had to make some modifications to the /etc/network/interfaces file:

auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
address 192.168.15.1 # For if I need to connect via Ethernet to the Raspi again
netmask 255.255.255.0
iface wlan0 inet static
address 192.168.60.1 # Wireless clients
netmask 255.255.255.0
allow-hotplug usb0
iface usb0 inet static
address 192.168.42.130
gateway 192.168.42.129 # IP of the HD2
netmask 255.255.255.0
up sysctl -w net.ipv4.ip_forward=1
up route add default gw 192.168.42.129 dev usb0

That is actually my whole file. I removed the gateway from eth0, so it would take the gateway to the usb0 device instead. It needs IP forwarding to be enabled as well, so I added that to the ifup command (net.ipv4.ip_forward=1). I removed all other directives from the wlan0 configuration as well.

I now set up "hostapd" which is a package that will allow to use the dongle in AP mode. My /etc/hostapd/hostapd.conf looks as follows:

interface=wlan0
driver=rtl871xdrv
ssid=PirateAP
hw_mode=g
channel=3
macaddr_acl=0
auth_algs=3
wmm_enabled=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=piratesown
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
beacon_int=100

It needs a bit more set up than that (read the full tutorial on elinux). I needed a modified binary of hostapd as well. I configured udhcpd (a micro dhcp daemon) to use the subnet 192.168.60.0/24 as shown above in the interfaces file.

Somehow I wasn't able to connect to the RasPi via WiFi. The connection got aborted each time. After debugging, I found out that wpa_supplicant was still active (though it shouldn't be, because the WiFi dongle is in host mode, and not in client mode). I decided to remove the wpasupplicant package altogether so it wouldn't cause me any more problems.

After that, I added the following rules to iptables, to take care of the routing between the different devices:

iptables -t nat -A POSTROUTING -o usb0 -j MASQUERADE
iptables -A FORWARD -i eth0 -j ACCEPT
iptables -A FORWARD -i wlan0 -j ACCEPT

The RasPi is now behaving as a router 🙂 !

If you're going to be setting this up yourself, you're gonna have to find a way to get the packages installed on your RasPi first (adb, hostapd udhcpd).

]]>
http://www.ce3c.be/256-using-a-raspberry-pi-as-a-wifi-repeater/feed/ 63
A couple of thoughts on hardening web servers http://www.ce3c.be/217-a-couple-of-thoughts-on-hardening-web-servers/ http://www.ce3c.be/217-a-couple-of-thoughts-on-hardening-web-servers/#comments Wed, 06 Mar 2013 00:48:48 +0000 http://www.ce3c.be/?p=217 There are a lot of things wrong with PHP, but it remains a very easy and convenient scripting language that I like to use for both websites and scripts. Webhosts however are reluctant to upgrade their PHP versions to 5.4.0 or newer. Those who already did, will have seen a spike in old PHP code getting owned through SQL injection. Default versions prior to 5.4.0 had safemode as well as "magic quotes" turned on, which allowed newbies to write code that would inherently be hardened against SQL injection. However, at some point, people forgot (how) to sanitize input. It was a convenience thing, that wouldn't stop a determined hacker anyway 🙂 ... But now that feature is gone (though I'd refer to it as a bug), and we're left with a mess of vulnerable scripts.

On shared hosting, an SQLi vulnerability on one site could mean the compromise of all the websites hosted on that same server. Even though solutions exist like mod_security, I'd like to know how we can limit the impact of a compromise after a successful attempt. How can a webhost sleep peacefully, knowing that no other customers will be affected when just one customer has a security vulnerability.

Just a couple of thoughts, all hypothetically:

We have the choice between creating a new UNIX user for each website, or creating a new UNIX user for each customer, and possibly giving them the same group. Both scenarios come with some advantages and disadvantages. A new system user for each website means privilege separation, enhanced security. A system user per customer who has multiple websites under his account, means a possible compromise of all of those websites when one of the websites is flawed.
We can use grsec to restrict users from accessing files that aren't in their home-directory (much like PHP safemode does).

As I offer IRC shell hosting, my customers require an IP per individual IRC server (I'll have to discuss RFC1459 in a different post, cause I'm a bit disgruntled about that too). Since giving each customer their own VPS isn't exactly profitable, we allow up to eight of them to be grouped together. (More is usually a bad idea: unlike web servers, IRC servers get often visited by packeters. For all of those having a Cisco router, PLEASE secure your SNMP settings...).
Using grsec we can bind every user to their own public IP (for both incoming and outgoing connections). They will not be able to connect from/bind to a public IP that they do not own. Grsec also prevents the users from seeing processes that they don't own (among other awesome things).

I run PHP with PHP-FPM as CGI (which became part of the core, yay!). The scripts are currently ran as the owner of the file (like with suphp/suexec) rather than the www-data user. When a website gets compromised, hackers might be able to get database details of other websites homed on the same server. Now what if ... we could actually make use of our 127.0.0.0/8 subnet and bind each user to such private IP. We then modify the permissions in the MySQL server to only allow access to the customer's database from the customer's own IP. That way, a hacker can't authenticate even if he manages to get the password by a directory traversal attack. This would require the PHP script to run under suexec/suphp. If grsec isn't available to bind the customer to his own IP, we can still hack our way around that via the LD_PRELOAD/LD_LIBRARY_PATH trick (though this isn't safe).

I like this idea. Private IP per customer. MySQL database permissions based on local IP. Why hasn't this been done already? Am I missing something obvious?

]]>
http://www.ce3c.be/217-a-couple-of-thoughts-on-hardening-web-servers/feed/ 1
Stripping colors & control codes in UnrealIRCd http://www.ce3c.be/207-stripping-colors-control-codes-in-unrealircd/ http://www.ce3c.be/207-stripping-colors-control-codes-in-unrealircd/#respond Thu, 24 Nov 2011 15:32:05 +0000 http://www.ce3c.be/?p=207 Apart from the channel mode +S and +c, there's already an Unreal module available that will strip out colors in private messages (called nocolorumode.c). But I wanted a usermode to allow stripping all colors/codes that are being sent to the client.

I needed to dig into the available hooks for this (since there is no manual available for them).

HOOKTYPE_PRIVMSG (aClient *cptr, aClient *sptr, aChannel *acptr, char *text, int notice)
HOOKTYPE_CHANMSG (aClient *cptr, aClient *sptr, aChannel *acptr, char *text, int notice)
HOOKTYPE_PACKET (aClient *from, aClient *to, char **msg, int *len)

Nocolorumode.c used HOOKTYPE_PRIVMSG for stripping out colors in PMs. You'd think that HOOKTYPE_CHANMSG would be the logical choice to strip out colors in channel messages.
I've come to understand however that that aproach won't work when using prefixes in PRIVMSG's (like PRIVMSG %#chan :text). When hooking into HOOKTYPE_CHANMSG, it's not possible to know about the prefix it's being sent to.
You could get it by overriding the command, but that's pretty ugly, and in this particular case would mean you end up rewriting the entire m_message function, which is just silly.

It's not possible to modify the text on a per-user basis. I need some users to receive the message with the colors stripped out, while others must receive the message in its untouched form.

There should be a hook that gets executed for every message that is soon to be received by the client, but there is none. The only option left is to strip the colors on the outgoing packet, using HOOKTYPE_PACKET.

http://pastebin.com/raw.php?i=38Rm4iRX

]]>
http://www.ce3c.be/207-stripping-colors-control-codes-in-unrealircd/feed/ 0
Counter-Strike 1.6, Windows 7, and lag spikes. The sequel. http://www.ce3c.be/179-counter-strike-1-6-windows-7-and-lag-spikes-the-sequel/ http://www.ce3c.be/179-counter-strike-1-6-windows-7-and-lag-spikes-the-sequel/#comments Mon, 06 Sep 2010 22:59:49 +0000 http://www.ce3c.be/?p=179 Honestly I've had a shitload of problems already running Counter-Strike (1.6) lagfree. Important detail is that I'm trying to play wireless.
On XP, there was the Wireless Zero Configuration Service that was causing lagspikes (if you're on XP and having lagspikes, check that link 🙂 ).
Now that I am on Windows 7, I'm not sure what to look for. I've done a clean OS install, updated my video card drivers, wlan drivers, but to no avail.

When enabling "net_graph 1" in the Counter-Strike console, I get the following result. The left side is during normal gameplay (a straight green line), and on the right there's a bouncy, interrupted line.

I've set my cvars to:

cl_updaterate 101
cl_cmdrate 101
rate 20000
max_fps 101

These are the vars I like, I'm just telling them for information.

I've taken the following steps in the hope to reduce the lagproblems,
I hope something of this will work for you:

1. Disabling MMCSS

Multiple forums stated that the lagspikes could be caused by the Multimedia Class Sheduler service.
Run regedit and remove in the entry DependOnService the line that says "MMCSS".

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Audiosrv

You will have to reboot after this. But try the rest of the proposed fixes first to save some time.

2. Disable Network Throttling

Because multimedia programs require more resources, the Windows networking stack implements a throttling mechanism to restrict the processing of non-multimedia network traffic to 10 packets per millisecond.

This implies that we should set the rate a bit higher to allow more packets. This seems a bit irrelevant, but I did it anyway.
Modify the following key in your registry, set NetworkThrottlingIndex to FFFFFFFF (hex) or 4294967295 (dec):

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Multimedia\SystemProfile

(thanks to stranger for pointing out that it had to be FFFFFFFF instead of FFFFFF)

3. Nagle's algorithm

Beyond the obvious settings in Windows or on your router, here’s a list of tweaks that may help quite a bit. It involves disabling Nagle’s algorithm, also commonly known as TCP no delay, which is basically an optimization of network traffic that tries to reduce overall packet volume but can cause extra latency in the connection. This should work on Windows 7 or Vista, though the same principle can probably applied to other operating systems as well.

Go to the registry key for your network interface card, it's one of the {XXXX-XXXX-XXXX-XXXX}. Look for one that has 192.168.x.x in it.

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters\Interfaces\{45115C55-0588-4D99-B404-CE3246685EEF}

Add a new DWORD 32-bit value here, name it TcpAckFrequency, then set it to 1. Do the same for TCPNoDelay.
This step would require a reboot also. (This is why you shouldn't have rebooted earlier lol.

4. Disable IPv6

In the Network and Sharing Center, change the adapter settings of the connection you're using (Properties).
On the Networking tab, remove the tick from the IPv6 box. If there's no difference, you can always tick it again.

References:

http://windows7forums.com/windows-7-games/22315-problem-latency-counter-strike-1-6-a.html
http://social.answers.microsoft.com/Forums/en-US/w7network/thread/af7aaf26-c5e3-478c-b1b8-2b1443d1306b
http://lifeandcode.net/2009/05/reduce-game-network-latency-in-windows-7-or-vista/

]]>
http://www.ce3c.be/179-counter-strike-1-6-windows-7-and-lag-spikes-the-sequel/feed/ 18
Cross-compiling QT C++ for windows on linux http://www.ce3c.be/152-cross-compiling-qt-c-for-windows-on-linux/ http://www.ce3c.be/152-cross-compiling-qt-c-for-windows-on-linux/#comments Tue, 08 Jun 2010 15:28:11 +0000 http://www.ce3c.be/?p=152

I've been trying to get cross-compiling to work on my linux box for quite some time now.
Now that it's finally working, I decided it was something that had to be shared 😀
I wanted to cross-compile to build nightlies for a new, open-source and cross-platform p2p application 🙂
To be clear, I'm not trying to write a full tutorial, just some basic guidelines to get you started.

Step 1: Set up a MinGW cross-compile environment

Normally this would take some time, but you can get a script that does it all for you from http://www.mingw.org/wiki/LinuxCrossMinGW.

$ sh x86-mingw32-build.sh
Follow the steps on your screen, this should be straight-forward.
For this guide, I assume you have installed MinGW in /home/user/mingw32/.

Step 2: Compile QT

We have two options here:
- Cross-compile QT on linux: don't. It'll take you too much time. There is a guide that covers this pretty well though on Divided Mind. It's for an older QT version, I didn't get it to work.
- Pre-compile QT on windows: this will take you far less time 🙂 This is what I'll try to cover a bit:
Install the SDK on your windows box (if you have QT Creator installed, you have the SDK already).
For me, QT was installed in C:\Qt\2010.02.1\qt. (Mind the qt subdirectory!) Now copy this whole directory and transfer it to your linux box.
I will assume you have put the contents in /home/user/qtwin/, which should contain an "include" and "lib" directory.

Step 3: Modding QT on linux

You should have QT installed on your linux box as well. Amongst the lines I executed on my debian box were:
$ apt-get build-dep qt4-qmake

I also needed this one:
$ apt-get install libphonon-dev

Now find out where the QT "mkspecs" directory is located on your linux box.
$ find / -type d -name "mkspecs"
This should at least return the directory where APT installed QT, and the directory that you transfered to /home/user/qtwin.
The APT directory was /usr/share/qt4/mkspecs in my case. Changedir to it, now:

$ cp -r win32-g++ win32-x-g++
The win32-g++ directory (and now win32-x-g++ too) contain a file called qmake.conf. It tells QT which tools to use for compiling.
Standard, it uses windows tools (like "xcopy" and "del"). You have to replace the ones in win32-x-g++/qmake.conf with their linux counterpart.
You'll also have to modifiy include and library dirs, and make it use the MinGW tools.
You can find my own modded qmake.conf on pastebin (it isn't perfect, but will give you an idea). This is a very important step, so make sure to get it right 🙂

Step 4: Compiling your application

Yes, we're here already 🙂
Changedir to your project directory and execute:
$ qmake -spec win32-x-g++

So generally compile as you do usually but with another -spec flag.
$ make
And, see if it works!

Kudos:

Links that helped me a lot:
]]>
http://www.ce3c.be/152-cross-compiling-qt-c-for-windows-on-linux/feed/ 6
Mobile Vikings tetheren naar laptop http://www.ce3c.be/140-mobilevikings-tetheren-laptop-gsm/ http://www.ce3c.be/140-mobilevikings-tetheren-laptop-gsm/#comments Thu, 24 Dec 2009 17:31:34 +0000 http://www.ce3c.be/?p=140 Ik ben jarenlang trouwe klant geweest bij Proximus: ik kocht elke maand braaf een herlaadkaart van 15 euro om mijn bonus van 1000 gratis sms'en te blijven behouden, die je kreeg bij het Generation tariefplan. Ik ben echter dat type klant die net iets meer verwacht van zijn operator: mobile internet om te beginnen en een API o.i.d. 🙂
Voor mobile internet betaal je je helaas blauw bij Proximus. Over een API was nergens iets terug te vinden, en hun klantendienst was enkel bereikbaar via telefoon. Op heel het internet heb ik geen enkel e-mailadres teruggevonden van Proximus.

Dat (en nog enkele kleine ergernissen) dwongen me om over te schakelen naar een andere operator (hoewel ik verder tevreden was van Proximus).
Zodoende ben ik nu lid van Mobile Vikings, een nieuwe gsm operator in België. Zij benutten het netwerk van Base om hun diensten aan te bieden. Ze zijn een MVNO ofwel Mobile Virtual Network Operator.

Voor elke 15 euro die je herlaadt bij Mobile Vikings krijg je maar liefst 1000 SMS'en en 1 GB datavolume!
Er zijn geen abonnementskosten, en je kan je kaart herladen via PayPal / overschrijving / Ogone.
Als je je huidig nummer wil behouden, ontvang je je nieuwe SIM-kaart zelfs gratis 🙂
Verder zijn ze ook druk bezig met hun API (waarvoor enkele sympathisanten al wat apps hebben gemaakt). Dat is voor mij een groot pluspunt.

Vanaf m'n nieuwe SIM-kaart ontvangen, geactiveerd en opgeladen was, ging ik the beauty booty dan ook meteen eens uitproberen!
Ik moest eerst m'n gsm nog instellen (access point name e.d.) maar nadat die klus geklaard was kon ik meteen op internet.

In eerste plaats was ik echter overgeschakeld om de internetverbinding te kunnen tetheren naar mijn laptop. (Daarmee kan je dus surfen in de auto, op de trein, overal.)

Tethering in draadloze communicatie is de mogelijkheid om een apparaat zonder internetverbinding (zoals desktop, notebook of laptop) aan te sluiten op een mobiel apparaat (zoals gsm of PDA) met mobiel internet om zo toegang tot internet te verschaffen aan het apparaat zonder internetverbinding. (Wikipedia)

Toen ik een nieuwe bluetooth adapter instelde op m'n laptop, wou die helaas niet direct werken... dus hoe loste ik dat op? 🙂
Vanaf hier ga ik ervan uit dat je internet werkend gekregen op je gsm (in mijn geval een Nokia 3120 classic), indien dat niet het geval is, zijn daar tutorials voor te vinden op de site van Mobile Vikings zelf 😉

Welnu, er is altijd te mogelijk om aan de slag te gaan met software bloat zoals de Nokia PC Suite, maar hier doe ik het even op de propere manier:
Als je gsm via bluetooth verbonden is met de computer en de bluetooth modem bij je Netwerken/Adapters staat, kun je normaal gesproken op die manier verbinden met internet. Helaas is dat in de realiteit niet zo. Wanneer ik probeer te verbinden krijg ik fout 777 naar mijn hoofd gesmeten: "De verbindspoging is mislukt omdat de modem (of een ander verbindgsapparaat) op de externe computer niet werkt."

Dit valt gelukkig heel makkelijk op te lossen! Vul voor zowel de gebruikersnaam als het wachtwoord "web" in. Bij het telefoonnummer zet je dan *99***1#. Tadaam 🙂 That works like a charm! De 1 in de code staat voor de standaardinstellingen op je gsm waarmee hij probeert te verbinden (als je met je gsm op internet kan, moet dit dus ook werken). Verder zou ook de code *99# moeten werken indien je een data kabel (usbkabel) gebruikt om je gsm aan te koppelen op je pc.

Toen dat allemaal achter de rug was, ging ik even naar speedtest.net uit nieuwsgierigheid naar de downloadsnelheid.
Geklokt op 25KB/s viel dat al bij al goed mee voor mobile internet! MV heeft momenteel slechts een Edge netwerk, maar de upgrade naar 3G in januari komt dichterbij, en de hogere snelheden dus ook 🙂

]]>
http://www.ce3c.be/140-mobilevikings-tetheren-laptop-gsm/feed/ 9