Floating ips

Working with Floating IPs

A Floating IP is a publicly-accessible static IP address that can be assigned to one of your Droplets. For a detailed description of the feature, you can read How To Use Floating IPs on DigitalOcean. You can manipulate floating IPs with .

subcommand Notes
List all Floating IP addresses.
Get the details for a Floating IP address.
Create a Floating IP in region.
Delete a floating IP address.

Assigning Floating IPs to Droplets

The command is used to assign or unassign a Floating IP from a Droplet.

subcommand Notes
Assign a Floating IP to the Droplet by its numeric ID.
Unassign a Floating IP.
Get details about a Floating IP action by its numeric ID.

Our Cloud Firewall Plan

Although we could just make two Cloud Firewalls, one tailored for each specific server, and apply one to frontend-01 and the other to database-01, we’re going take a more flexible approach to how we organize our rules.

First, we want to leave ourselves prepared for a future where we may need to add a third type of service to this system (perhaps a cache server). So we’re going to split up our firewall rules based on roles, not by physical server. We can apply multiple Cloud Firewalls to each Droplet, so it’s not a problem to make these firewalls fine-grained and modular.

Note: If you would like a more in-depth exploration of best-practices regarding structuring your Cloud Firewalls, please read How To Organize DigitalOcean Cloud Firewalls.

If we break things down a bit, we notice that both of our servers actually have multiple functions. There’s the primary function of either serving web pages or database information, and there’s also a management function provided by the SSH service. It would make good sense for us to create a management firewall, a frontend firewall, and a database firewall.

To handle the future scenario where we scale our web or database services to multiple hosts, we’ll use DigitalOcean’s tagging feature to organize our Droplets by role. Tags are simple labels we can apply to Droplets to categorize them and address whole groups of servers at once. The Cloud Firewall service can apply firewall rules to all Droplets in a tag, making it easy to provision new Droplets with the correct firewall rules already in place.

An additional bonus – and something that would be difficult do in a dynamic way using – is that Cloud Firewalls can restrict inbound access based on tags. So for instance, our database servers only need to be accessible from our frontend servers. The current setup has the database open to anybody on the network. We’ll lock that down to only our Droplets tagged with frontend.

Let’s summarize the three firewalls we need to set up, in plain language:

  • Management: allow inbound traffic to TCP port 22 from any host
  • Frontend: allow inbound traffic to TCP ports 80 and 443 from any host
  • Database: allow inbound traffic to TCP port 3306 only from frontend tagged servers

We’re not going to restrict outbound traffic at all in this tutorial. It’s not a bad idea, but it does take some care to make sure you don’t break auto-update mechanisms and other critical features of the underlying operating system.

Now that we have a plan for our new firewalls, let’s get started.

Parameters

Parameter Choices/Defaults Comments
droplet_ids list / elements=string List of droplet ids to be assigned to the firewall
inbound_rules list / elements=dictionary / required Firewall rules specifically targeting inbound network traffic into DigitalOcean
ports string / required The ports on which traffic will be allowed, single, range, or all
protocol string Choices: udp
tcp
icmp
Network protocol to be accepted.
sources dictionary / required Dictionary of locations from which inbound traffic will be accepted
addresses list / elements=string List of strings containing the IPv4 addresses, IPv6 addresses, IPv4 CIDRs, and/or IPv6 CIDRs to which the firewall will allow traffic
droplet_ids list / elements=string List of integers containing the IDs of the Droplets to which the firewall will allow traffic
load_balancer_uids list / elements=string List of strings containing the IDs of the Load Balancers to which the firewall will allow traffic
tags list / elements=string List of strings containing the names of Tags corresponding to groups of Droplets to which the Firewall will allow traffic
name string / required Name of the firewall rule to create or manage
oauth_token string DigitalOcean OAuth token. There are several other environment variables which can be used to provide this value. i.e., — ‘DO_API_TOKEN’, ‘DO_API_KEY’, ‘DO_OAUTH_TOKEN’ and ‘OAUTH_TOKEN’
aliases: api_token
outbound_rules list / elements=dictionary / required Firewall rules specifically targeting outbound network traffic from DigitalOcean
destinations dictionary / required Dictionary of locations from which outbound traffic will be allowed
addresses list / elements=string List of strings containing the IPv4 addresses, IPv6 addresses, IPv4 CIDRs, and/or IPv6 CIDRs to which the firewall will allow traffic
droplet_ids list / elements=string List of integers containing the IDs of the Droplets to which the firewall will allow traffic
load_balancer_uids list / elements=string List of strings containing the IDs of the Load Balancers to which the firewall will allow traffic
tags list / elements=string List of strings containing the names of Tags corresponding to groups of Droplets to which the Firewall will allow traffic
ports string / required The ports on which traffic will be allowed, single, range, or all
protocol string Choices: udp
tcp
icmp
Network protocol to be accepted.
state string Choices:
present
absent
Assert the state of the firewall rule. Set to ‘present’ to create or update and ‘absent’ to remove.
tags list / elements=string List of tags to be assigned to the firewall
timeout integer Default:30 The timeout in seconds used for polling DigitalOcean’s API.
validate_certs boolean Choices: no
yes
If set to , the SSL certificates will not be validated. This should only set to used on personally controlled sites using self-signed certificates.

Create New Rules

You can create new inbound and outbound rules by opening the New rule select list under Inbound Rules or Outbound Rules, respectively. You can use a preset protocol or create a custom rule.

Note

You can only define firewall rules to restrict traffic to and from ports based on connection types, sources, and destinations. You cannot define a rule to restrict traffic based on HTTP headers, such as , , or .

From Presets

There are several common protocols available which will fill the Protocol and Port Range fields automatically. For example, selecting will auto-fill the Protocol with and the Port Range with HTTP’s default of port 80.

If one of these services is listening on a non-standard port, you can configure it by creating a custom rule.

Custom Rules

To add a custom rule, choose Custom, which allows you to define the protocol, port range, and source or destination.

  • Protocol. You can choose either TCP or UDP. Because ICMP has no port abstraction, to allow ICMP traffic, you select it directly from the New rule dropdown.

  • Port Range. For the TCP and UDP protocols, you can specify:

    • A single port.
    • A range of ports by entering the starting and ending ports separated by a dash with no spaces, e.g. . To open multiple non-sequential ports, create a separate rule for each.
    • All ports by leaving the field blank.
  • Sources for inbound rules, which lets you restrict the source of incoming connections. You can restrict incoming connections to:

    • Resources or tags by entering the name of the resource or tag. This includes Droplets, VPCs, Kubernetes clusters, , load balancers, and IPv4/IPv6 addresses.
    • IP addresses or IP ranges by entering individual IP addresses or entering a CIDR. For example, enter the CIDR 10.128.0.0/16 to a rule allows incoming traffic from any IP address between the 10.128.0.0 and 10.128.255.255. The same properties applies to IPv6 addresses and CIDRs.
    • Types of IP addresses by choosing All IPv4 or All IPv6 in the sources field. This allows all IP addresses of a specific type (either all IPv4 addresses or all IPv6 addresses) to connect to the Droplet. If you are , enter (IPv4) or (IPv6) into the field of the object allow incoming traffic from a specific type of IP address.
  • Destinations for outbound rules, which lets you restrict the destination of outgoing connections.

    You can limit the sources/destinations to:

    • Droplets, chosen by name, IP address, or tag
    • DigitalOcean Load Balancers, chosen by name, IP address, or tag
    • DigitalOcean Kubernetes clusters, chosen by name, or tag
    • Non-DigitalOcean servers by IP addresses, subnets, or CIDR ranges.

Persisting Iptables Rules

For now, all of your other Droplets in the same region can connect to the current system, while traffic from systems you don’t control is blocked. If the system reboots, however, the iptables rules will disappear. It’s also likely that you will create new Droplets (or delete the existing ones) at some point in the future. In order to deal with these problems, we’ll make sure that rules persist on restart, and schedule to run on a regular basis and make any necessary changes to the firewall.

Persisting Rules on CentOS 7

By default, CentOS 7 uses the firewalld service in place of iptables. Since we already installed the package above, we can use to stop this service and mask it, ensuring that it won’t be restarted:

Now enable the service:

With the service in place, save the current firewall rules:

Testing Rule Persistence

You may wish to reboot the system, reconnect, and check that the rules have persisted. First, reboot:

Now, reconnect to your Droplet (this will take a few seconds), and check the rules:

Scheduling a Cron Job to Update Iptables Rules

As a final step, we’ll make sure that runs periodically so that it catches changes in your collection of Droplets.

Begin by creating a new script called , using (or your editor of choice):

Paste the following, uncommenting the appropriate line for your distribution by deleting the leading :

/opt/droplan/refresh.sh

Exit and save the file, then mark it executable:

Next, create a new file at :

Add the following line to the file in order to run the script as root every 5 minutes:

crontab

This will run the script once every 5 minutes, as indicated by in the first field, and log its most recent output to .

Exit and save the file. You can now use the command, which displays the output of another command every few seconds, to make sure that the script runs successfully:

Once the script runs, you should see output something like the following:

On Debian-derived systems, won’t display any output.

Press Ctrl-C to exit .

Note: Since the API is rate-limited, you may need to tune the frequency of updates if you have many Droplets. You can read more about or the API itself.

1.2.0 (April 23, 2019)

FEATURES:

  • New Resource: (#42). Thanks to @slapula!
  • New Resource: (#198) Thanks to @slapula!
  • New Resource: (#204)
  • New Resource: (#207)

IMPROVEMENTS:

  • provider: The DigitalOcean API URL can now be overridden using attribute (#84).
    Thanks to @protochron!
  • provider: Refactor logic for logging API requests/responses (#190). Thanks to @radeksimko!
  • resource/digitalocean_loadbalancer: Add support for enabling PROXY Protocol (#199).
  • docs/digitalocean_firewall: Update syntax to be compatible with Terraform 0.12-beta (#201).
  • resource/digitalocean_droplet: Expose uniform resource name (URN) attribute for use with Projects resource (#215).
  • resource/digitalocean_loadbalancer: Expose uniform resource name (URN) attribute for use with Projects resource (#214).
  • resource/digitalocean_domain: Expose uniform resource name (URN) attribute for use with Projects resource (#213).
  • resource/digitalocean_volume: Expose uniform resource name (URN) attribute for use with Projects resource (#212).
  • resource/digitalocean_floating_ip: Expose uniform resource name (URN) attribute for use with Projects resource (#211).
  • resource/digitalocean_spaces_bucket: Expose uniform resource name (URN) attribute for use with Projects resource (#210).

BUG FIXES:

  • resource/digitalocean_certificate: Fix issue when using computed values for custom certificates (#163).
  • resource/digitalocean_droplet: Prevent unexpected rebuilds for Droplets created using image slugs when the backing image is updated (#152).

NOTES:

  • This provider is now built and tested using Go 1.11.x (#178).
  • Dependencies for this provider are now managed using Go Modules (#187).

Бесплатные дополнительные IP в облачном хостинге DigitalOcean

Если вы еще не пробовали облачный хостинг DigitalOcean, то видимо прогресс обошел вас стороной, ибо на данный момент это пожалуй одно из лучших облачных решений в мире, где всего за $5 вы можете получить дроплет в одной из 6 точек присутствия в Европе/США/Канаде или Сингапуре, которого хватит за глаза для любого персонального блога или одностраничника.

Поскольку это облачный хостинг, то часть своих, наиболее критичных к простою, сервисов я держу именно на серверах Digital Ocean и до определенного момент исповедовал принцип 1 дроплет = 1 сайт, чтобы не было пересечения по IP и каких то возможных вопросов.

Но с оказией узнал, что оказывается с недавнего времени в Digital Ocean появилась возможность бесплатно подключить дополнительный IP адрес. Причем на халяву выдается по одному IP адресу на дроплет, которые можно привязать по одному к каждому дроплету для резервирования или же просто дополнительного IP адреса.

Более того, при желании, вы можете перепривязывать эти IP к любой машине из вашего пула. Именно по этому он называется плавающий IP – Floating IP. Задумано это как реализация отказоустойчивости HA, т.е при падении какой то сетки, вы можете перенаправить трафик на другой IP или же просто использовать round-robin для открытия сайта с рандомного IP адреса, но его также можно использовать и для других вебсайтов, чтобы они не пересекались координатами с соседями по серверу.

Делается это в несколько шагов – для начала идем в админку Digital Ocean и из верхнего меню выбираем пункт Networking. На новой странице видим единственный пункт Assign a Floating IP в котором из выпадающего меню выбираем нужный нам дроплет и жмем на клавишу Assign a Floating IP.

IP поставляется не напрямую на дроплет, а посредством технологии NAT, что и позволяет почти мгновенно пробрасывать нужный IP на любую из машин, фактически меняя сетевую конфигурацию на лету.

Но для того чтобы привязать IP, нам нужно задать на основном интерфейсе внутренний адрес на который будет пробрасываться наш внешний IP. Поэтому в файле /etc/sysconfig/network-scripts/ifcfg-eth0 прописываем ручками дополнительный IP который выдаст система в диалоге Assign a Floating IP.
IPADDR2=10.14.0.5
можно просто сказать из консоли ssh управления дроплетом# echo ‘IPADDR2=10.14.0.5′ | sudo tee -a /etc/sysconfig/network-scripts/ifcfg-eth0
после чего перегрузить сетку# service network restart

Если у вас нет ssh-клиента, то вы можете воспользоваться веб-консолью VNC доступной из админки. Для этого надо сказать в верхнем меню Droplet -> кликнуть в нужный сервер -> в разделе Console Access кликнуть в клавишу Console Access -> после чего у вас откроется VNC сессия. Если вы видите просто черный экран, то в него надо щелкнуть мышью и нажать любую клавишу. Тогда появился логин-промт, предлагающий ввести логин и пароль доступа, что вам выдавались при создании дроплета.

После перезагрузки системы вам надо добавить айпишник в ваш вебсервер, чтобы он обрабатывал запросы к нему. Т.к у меня стоит консоль управления хостингом Vesta CP, то я добавил внутренний адрес с /16 маской (255.255.0.0) и указанием на внешний адрес.

После чего все стало нормально работать.

Возможно что у вас не будет открываться сайт, тогда вам надо добавить соответствующее правило в фаервол, чтобы он не блокировал передачу пакетов по внутренней сетке.

Единственный момент, что дополнительные IP адреса бесплатные если вы их используете, если же вы их заказали, но не назначили на дроплет, т.е они у вас простаивают, то Digital Ocean слупит с вас за них денежку, причем не малую, в районе $4.5. Так что не стоит особо жлобиться и набирать дополнительные IP больше чем вы можете израсходовать.

VN:F

please wait…

Rating: 3.8/10 (42 votes cast)

VN:F

Rating: +1 (from 15 votes)

Бесплатные дополнительные IP в облачном хостинге DigitalOcean, 3.8 out of 10 based on 42 ratings

Return Values

Common return values are documented , the following are the fields unique to this module:

Key Returned Description

assign_status

string

changed Assignment status (ok, not_found, assigned, already_assigned, service_down)
Sample:
assigned

data

dictionary

changed a DigitalOcean Droplet
Sample:
{‘droplet’: {‘backup_ids’: [], ‘created_at’: ‘2014-11-14T16:36:31Z’, ‘disk’: 20, ‘features’: , ‘id’: 3164494, ‘image’: {}, ‘kernel’: {‘id’: 2233, ‘name’: ‘Ubuntu 14.04 x64 vmlinuz-3.13.0-37-generic’, ‘version’: ‘3.13.0-37-generic’}, ‘locked’: True, ‘memory’: 512, ‘name’: ‘example.com’, ‘networks’: {}, ‘region’: {}, ‘size’: {}, ‘size_slug’: ‘512mb’, ‘snapshot_ids’: [], ‘status’: ‘new’, ‘tags’: , ‘vcpus’: 1, ‘volume_ids’: []}, ‘ip_address’: ‘104.248.118.172’, ‘ipv6_address’: ‘2604:a880:400:d1::90a:6001’, ‘private_ipv4_address’: ‘10.136.122.141’}

msg

string

changed Informational or error message encountered during execution
Sample:
No project named test2 found

resources

dictionary

changed Resource assignment involved in project assignment
Sample:
{‘assigned_at’: ‘2021-10-25T17:39:38Z’, ‘links’: {‘self’: ‘https://api.digitalocean.com/v2/droplets/3164494’}, ‘status’: ‘assigned’, ‘urn’: ‘do:droplet:3164494’}

Step 4 — Testing Our Firewalls

To test our firewalls, we’re going to log in to a third server, and use a utility called to scan our web and database servers. is a port scanner that will scan our hosts and tell us which ports are open, closed, or filtered.

Log in to another Ubuntu 16.04 server that’s in the same region as your frontend-01 and database-01 servers. Then install :

Then, use to scan the web server’s public IP:

Note the output about . If the firewall was not functioning, these would show as . Filtered means that can’t even connect to determine if the port is open or closed.

Note also that we see our SSH, HTTP, and HTTPS ports are open, as expected.

Next, we’ll scan the database server. Be sure to use the Droplet’s private IP if you’ve set it up that way, as that’s what the MySQL database will be listening on:

We see that most ports are filtered, as before. However, we’re only seeing the SSH port as open, with no MySQL port available. Recall that we restricted database access to only those servers tagged with frontend. Switch back over to the DigitalOcean Control Panel and add the frontend tag to the server you’re using from. Then rerun the command:

The MySQL port now shows as open. We’ve verified that both of our servers are now protected by our Cloud Firewall rules. You can now restore this test server’s original firewall settings by returning to the Control Panel and removing the Droplet’s frontend tag.

Test High Availability

It’s important to test that a high availability setup works, so let’s do that now.

Currently, the Floating IP is assigned to the primary node. Accessing the Floating IP now, via the IP address or by the domain name that is pointing to it, will simply show the index page of the primary server. If you used the example user data script, it will look something like this:

This indicates that the Floating IP is, in fact, assigned to the primary Droplet.

Now, let’s open a local terminal and use to access the Floating IP on a 1-second loop. Use this command to do so, but be sure to replace the URL with your domain or Floating IP address:

Currently, this will output the same Droplet name and IP address of the primary server. If we cause the primary server to fail, by powering it off or stopping the Heartbeat service, we will see if the Floating IP gets reassigned to the secondary server.

Let’s reboot the primary server now. Do so via the DigitalOcean Control Panel or by running this command on the primary server:

After a few moments, the primary server should become unavailable. Pay attention to the output of the loop that is running in the terminal. You should notice output that looks like this:

That is, the Floating IP address should be reassigned to point to the IP address of the secondary server. That means that your HA setup is working, as a successful automatic failover has occurred.

You may or may not see the error, which can occur if you try and access the Floating IP between the primary server failure and the Floating IP reassignment completion.

Now, you may power on your primary Droplet, via the DigitalOcean Control Panel. Because Heartbeat is configured with the primary Droplet as the preferred host to run the Floating IP reassignment script, the Floating IP will automatically point back to the primary server as soon as it becomes available again.

Step 2 — Creating Cloud Firewalls

We’re going to set up our Cloud Firewalls now. We’ll do the frontend firewall first, followed by database, then management. This order should result in no service disruptions for your website visitors, but we will temporarily lose the ability to make new SSH connections. This will not affect already established connections.

The Firewalls service is available under the Networking section on the DigitalOcean Control Panel. Once there, click the Firewalls tab, then click the Create Firewall button to get started.

Creating the Frontend Firewall

On the Create Firewall page, we need to fill out a Name, configure our Inbound Rules, and select which Droplets to apply the firewall to. We will leave the Outbound Rules section as is.

We’re creating the frontend firewall first, so put frontend-fw in the Name field.

Note: We’ll add -fw to the end of our firewall names to disambiguate them. Though the Control Panel interface uses icons to differentiate between resource types, it could get confusing if you’re using the command line or API and have multiple frontend items, for instance.

Next, we need to delete the default SSH rule from the Inbound Rules section. We’ll break this rule out into the management firewall for flexibility. Use the Delete link on the right-hand side of the page to delete the SSH rule now.

Then, click on the New rule dropdown and select HTTP. This will autofill the correct protocol (TCP) and port (80), and by default allow traffic from all IPv4 and IPv6 addresses. This is what we want.

If you have HTTPS enabled, repeat the above process to create a second rule, selecting HTTPS this time. Your Inbound Rules section will end up like this:

Finally, in the Apply to Droplets field, start typing frontend then select the frontend tag when it is auto-suggested.

Click the Create Firewall button. The new firewall will be created and applied to any Droplet with the frontend tag. You will be returned to an updated firewall summary page showing your new firewall:

Now we’ll create the database firewall.

Creating the Database Firewall

On the Firewalls page, click Create Firewall again. The process will be mostly the same as for our frontend firewall.

Type database-fw into the Name field.

In Inbound Rules, delete the default SSH rule. Then, create a new rule using the dropdown, selecting MySQL. A default MySQL rule will be created allowing access to port 3306 from all IPs. Delete All IPv4 and All IPv6 from the Sources field. We want only our frontend servers to be able to access the database. Start typing frontend into the Sources box, and select the frontend tag when it is auto-suggested. Now any Droplet with that tag applied will be allowed access to the database server. All other IPs are blocked.

Leave the Outbound Rules as is. Under Apply to Droplets, apply this firewall to the database tag, then click Create Firewall. Once again, you’ll be returned to the firewall summary page:

Note that both firewalls show that they are applied to one Droplet each. If you load your website, it should still load fine. Now let’s re-enabled management via SSH.

Creating the Management Firewall

Click Create Firewall one last time. Add management-fw to the Name field.

The default SSH rule is all we need for this firewall. This will allow any IP to connect to port 22.

Alternately, you could change the Sources field of the SSH rule to a specific IP that you’ll be connecting from. For instance, if your office has a static IP, and you want to restrict SSH access to only connections from the office, put that IP in Sources, replacing All IPv4 and All IPv6. If your IP ever changes in the future, you’ll just have to update this one rule to restore management access, another advantage of planning ahead and making our rules modular.

Under Apply to Droplets, add both the frontend and database tags, then click Create Firewall. Let’s take a look at our final firewall summary:

At this point, our Cloud Firewall should be fully functional, but we also still have the host-based firewalls active. Let’s disable those, then test our connections.

Заполнение команд капли

В этом случае мы хотим предоставить простой ресурс капли. Есть пара параметров, которые мы собираемся использовать. Мы хотим использовать их самый дешевый доступный план, в центра обработки данных, и добавьте пару опций, которые сделают Droplet более гибким в будущем.

  • Изображение капли:
  • Область:
  • Размер:

Теперь, когда у нас есть наши базовые атрибуты, давайте создадим конфигурацию Terraform для этой капли.

Дополнительные команды, которые мы добавляем здесь, предназначены для мониторинга, ipv6 и частных сетей. Мониторинг означает, что у вас будут метрики, такие как процессор и память, внутри облачной консоли DigitalOcean. Затем вы можете установить оповещения для этих показателей, так что это очень полезно в будущем. IPv6 означает, что ваша капля будет доступна из IPv6, что помогает защитить ваши капли в будущем. Наконец, частная сеть означает, что ваша капелька получит адрес, доступный другим капелькам, но не общедоступный интернет.

Есть еще одна очень полезная возможность — пользовательские данные. Для Linux это позволяет вам запускать определенные команды при подготовке виртуальной машины, такие как обновление пакетов. Мы можем включить это прямо в конфигурацию Terraform, добавив этот атрибут в.

Если вы начинаете делать много с Вы можете сохранить данные в файле YAML, а затем включить их в объявление ресурса.

Our Current Firewall Situation

Right now, both of our servers have firewalls set up using the utility. is an easy-to-use wrapper around Linux’s iptables firewall engine. Log in to both servers now and let’s check the status of our firewalls:

First, on the web server, frontend-01:

In the output, after we are shown that the firewall is, by default, denying all incoming connections and allowing all outgoing connections. Additionally we have four rules that allow incoming IPv4 and IPv6 TCP connections () to ports 22 (SSH), 80 (HTTP), and 443 (HTTPS).

Let’s do the same thing on the database server, database-01:

This output is similar, except we’ve swapped the two Nginx ports for port 3306, which is the standard MySQL port. Now that we know our current setup, let’s plan our replacement.

Working with Block Storage Volumes

Creating, Deleting, and Inspecting Block Storage Volumes

The command can be used to create, delete, or get information about DigitalOcean’s Block Storage volumes. For more information about this feature, read our guide on How To Use Block Storage on DigitalOcean.

subcommand Notes
List volumes.
Create a volume. The name, region, and size are mandatory.
Get volume by numeric ID.
Delete volume.
Snapshot volume.

Initiating Volume Actions

The command lets you trigger actions for a volume, including attaching volumes to and detaching volumes from Droplets.

subcommand Notes
Attach a volume to a Droplet.
Detach a volume from a Droplet.
Resize a volume.
Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Мой редактор ОС
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: