Я написал сервер (Ubuntu 14.04 LTS Server) - клиент - программа Java.
С помощью этой программы я могу отправить текст со своего Android-смартфона на мой сервер, сохранив его в файле receivedData
.
Программа работает под пользователем, которому по умолчанию не назначена оболочка и нет доступа к конфиденциальным данным или программам.
Единственная проблема безопасности, о которой я могу думать, это нехватка памяти из-за тонны файла гигабайта receivedData
, который не имеет проверки размера. Или, конечно, DoS-атака, но я не думаю, что мой сервер так важен ...
Программа предназначена только для обучения и не должна использоваться никакими клиентами / хакерами (конечно;)), но ты никогда сейчас ..
Итак, кто-нибудь может сказать мне, возможно ли напрямую создать файл receivedData
с ограниченным размером файла. В тот момент, когда он достигает размера файла, он должен запретить receivedData
предотвращение появления OOM.
Если нет, мне нужно будет внедрить это в Java-программу ...
Это можно сделать двумя способами:
ulimit
или с помощью системного вызова setrlimit
(который, в свою очередь, вызывает ulimit
). ulimit
/ [ 1110] Из man 2 setrlimit
:
RLIMIT_FSIZE
The maximum size of files that the process may create. Attempts
to extend a file beyond this limit result in delivery of a
SIGXFSZ signal. By default, this signal terminates a process,
but a process can catch this signal instead, in which case the
relevant system call (e.g., write(2), truncate(2)) fails with
the error EFBIG.
Я не уверен, как можно вызвать функцию setrlimit
из Java, но это Вопрос U & amp; L может помочь. В качестве альтернативы, оберните сервер Java в скрипт:
#! /bin/bash
ulimit -f 1073741824 # 1GB
java ....
Я предполагаю, что файловая система ext4 не уверена в других. Во-первых, нам нужно включить квоту в файловой системе. Отредактируйте /etc/fstab
и добавьте usrquota
к опциям монтирования соответствующего раздела. Например, если мы делаем это для /
, последняя запись будет выглядеть примерно так:
UUID=... / ext4 errors=remount-ro,usrquota 0 1
Затем включите ее после перезапуска:
sudo quotaon /
Я приду ваш сервер запущен от имени другого пользователя (скажем, restricted_user
). Если нет, создайте его, если вы не хотите, чтобы на ваши обычные процессы влияли.
Затем выполните:
sudo edquota restricted_user
, что откроет редактор.
Disk quotas for user restricted_user (uid 1001):
Filesystem blocks soft hard inodes soft hard
/dev/sdd1 1087940 943718 1048576 9956 0 0
Установите мягкие и жесткие ограничения для соответствующих значений (это блоки по 1024 байта, поэтому разделите свой предел на 1024). Сохраните и выйдите.
Тогда пользователь не сможет превысить общее использование 1G в этой файловой системе, считая все файлы, принадлежащие ему.
Естественно, вы все равно должны проверить размер в вашей серверной программе.
ОБНОВЛЕНИЕ:
ответ muru идеально подходит для размера файла, я здесь даю решение, как измерить сам каталог, не только файл.
<час>нет такой вещи, прямой начиная с соглашения о файловой системе с папкой как файл файлов, и его предел является самой целой файловой системой.
Поэтому как обходное решение для Вашей проблемы можно сделать прием, создающий виртуальную файловую систему, и смонтировать его на определенном (пустом) каталоге.
создают точку монтирования виртуальной файловой системы для монтирования на (~/, тест для меня)
mkdir ~/test
создают файл, полный/dev/zero, достаточно большого к максимальному размеру, который Вы хотите зарезервировать для виртуальной файловой системы (я делаю здесь для 1 МБ)
dd if=/dev/zero of=test.img bs=1024 count=0 seek=1024
формат, этот файл с ext4 файловой системой
mke2fs test.img
монтирует недавно отформатированное дисковое пространство в каталоге, который Вы создали как точка монтирования
mount -o loop test.img ~/test
Тогда использование этот каталог
Я сказал бы, что является самым безопасным проверить размер файла в программе Java.
можно добавить в любой файл, у Вас есть доступ для записи к, пока существует достаточно пространства в разделе, таким образом, Вы не можете ограничить размер файла непосредственно.
единственная вещь, о которой я могу думать, состоит в том, чтобы создать раздел только для этого файла, таким образом, размер файла будет ограничен размером раздела. Кроме того, при форматировании раздела как FAT32 файл мог бы иметь максимальный размер 4 гибибайт.
Не видя Ваш код, трудно сказать, было ли Ваше приложение OOM или нет.
Обычно, Вы читали бы, управляемый блок данных (скажите, что 1 МБ), от сокета и пишут что блок данных непосредственно в файл. Тем путем Вы никогда не хранили бы больше, чем временный блок в памяти в любой момент.
Обычно это похоже:
FileOutputStream fos = new FileOutputStream("receivedData");
InputStream is = clientSocket.getInputStream();
byte[] buffer = new byte[1024];
int read;
while((read = is.read(buffer)) != -1) {
fos.write(buffer);
};
Вы могли затем добавить в противоречии с циклом с условием продолжения для подсчета, сколько байтов было записано в файл и завершается, сокет должен он пробегаться через предопределенную сумму или рядом с потреблением всего доступного дискового пространства.